Components构建单页面应用,远程分页类

润饰和收尾

这里有一些小技巧和诀窍你可以用来改善你的应用。

当一个菜单条目被选择后,关闭应用的抽屉菜单(drawer):

JavaScript

<core-menu … on-core-select=”{{menuItemSelected}}”>

1
<core-menu … on-core-select="{{menuItemSelected}}">

JavaScript

template.menuItemSelected = function(e, detail, sender) { if
(detail.isSelected) { scaffold.closeDrawer(); } };

1
2
3
4
5
template.menuItemSelected = function(e, detail, sender) {
  if (detail.isSelected) {
    scaffold.closeDrawer();
  }
};

为导航选择条目设置不同的图标:

XHTML

<paper-item noink> <ore-icon icon=”label{{route != page.hash ?
‘-outline’ : ”}}”></core-icon> <core-animated-pages …
on-tap=”{{cyclePages}}”>

1
2
3
<paper-item noink>
  &lt;ore-icon icon="label{{route != page.hash ? ‘-outline’ : ”}}">&lt;/core-icon>
<core-animated-pages … on-tap="{{cyclePages}}">

JavaScript

template.cyclePages = function(e, detail, sender) { // If click was on a
link, navigate and don’t cycle page. if (e.path[0].localName == ‘a’) {
return; } e.shiftKey ? sender.selectPrevious(true) :
sender.selectNext(true); };

1
2
3
4
5
6
7
8
template.cyclePages = function(e, detail, sender) {
  // If click was on a link, navigate and don’t cycle page.
  if (e.path[0].localName == ‘a’) {
    return;
  }
  e.shiftKey ? sender.selectPrevious(true) :
               sender.selectNext(true);
};

//核心计算 并以数组的形式返回查询sql 语句的必须值 limit a,b;
function main(){
  $this->totpages =
ceil($this->total_rows/$this->page_total_rows);//总页数计算
  //获得当前页码——————-
  if(!isset($_get[‘pages’]))
  {
  $this->pages_current = 1;
  }else
  {
   $this->pages_current = intval($_get[‘pages’]);
   //判断页面不为0
   if($this->pages_current < 1){
   $this->pages_current = 1;
   }
   //判断页面不能大于最大页码数量
   if($this->pages_current > $this->totpages){
   $this->pages_current = $this->totpages;
   }
   //注销url 参数 pages 和 total_rows 为了更好的传递其他url参数
   if(isset($_get[‘pages’])){unset($_get[‘pages’]);}
   if(isset($_get[‘total_rows’])){unset($_get[‘total_rows’]);}
  
  }
  //获得当前页码——————–
  $limit[‘a’] = $start = ($this->pages_current –
1)*$this->page_total_rows;
  $limit[‘b’] = $this->page_total_rows;
  //获得当前页面名称
  $urlin =
explode(‘/’,$_server[‘php教程_self’]);
 
  $tot_url = sizeof($urlin);
  $this->current_url =$urlin[$tot_url-1];
  //获得当前页面传递的url
  if(sizeof($_get) > 0){
   foreach($_get as $key=>$values){
    $urlsget .= $key.’=’.$values.’&’;
   }
   $this->current_url .= ‘?’.$urlsget;
   $this->ask = ”;
  }else{$this->ask = ‘?’;}
  //输出样式
  echo $this->style;
  return $limit;
}
//展示分页
//1 第一页
function firstpage(){
  echo ‘<div class=”pages_norename”><a
href=”‘.$this->current_url.'”>首页</a></div>’;
}
//2 上一页
function prepage(){
  echo ‘<div class=”pages_norename”><a
href=”‘.$this->current_url.$this->ask.’pages=’.($this->pages_current-1).'”>上一页</a></div>’;
}
//3 下一页
function nextpage(){
  echo ‘<div class=”pages_norename”><a
href=”‘.$this->current_url.$this->ask.’pages=’.($this->pages_current+1).'”>下一页</a></div>’;
}
//4 最后一页
function  lastpage(){
  echo ‘<div class=”pages_norename”><a
href=”‘.$this->current_url.$this->ask.’pages=’.($this->totpages).'”>尾页</a></div>’;
}
//中间过渡页
function morepage(){
  if($this->pages_current == 1){$newtj =
$this->pages_current+9;}
  elseif($this->pages_current  == 2){$newtj =
$this->pages_current+8;}
  elseif($this->pages_current == 3){$newtj =
$this->pages_current+7;}
  else{$newtj = $this->pages_current+6;}
   for($i=$this->pages_current-3;$i<=$newtj;$i++){
    if($i==$this->pages_current){$strong ='<strong>’; $strong2
='</strong>’;}else{$strong=”;$strong2=”;}
    if($i >=1){echo ‘<div class=”pages_nore_more”><a
href=”‘.$this->current_url.$this->ask.’pages=’.$i.'”>’.$strong.$i.$strong2.'</a></div>’;}
    if($i >= $this->totpages){
    break;
    }
   }
}
//跳转页面
function changepage(){
  echo ‘<div class=”pages_se”><select name=”dd”>’;
  for($i=1;$i<=$this->totpages;$i++){
  if($this->pages_current == $i){$selected = ‘
selected=”selected”‘;}else{$selected = ”;}
  echo ‘<option
value=”‘.$i.'”‘.$selected.’>第’.$i.’页</option>’;
  }
  echo ‘</select></div>’;
}
}
?>
该类可以自动识别 url 参数 避免了一般分页类 丢失url参数问题
样式 可以通过style属性 进行修改
提供 首页 上一页 下一页 尾页 中间 过渡页 跳转菜单功能

自动绑定模板(template)

为了利用<polymer-element>外的绑定数据,包装一个Yo应用?利用里面的自动绑定<template>元素:

XHTML

<body unresolved fullbleed> <template is=”auto-binding”>
<core-scaffold id=”scaffold”> … </core-scaffold>
</template> </body>

1
2
3
4
5
6
7
<body unresolved fullbleed>
  <template is="auto-binding">
    <core-scaffold id="scaffold">
      …
    </core-scaffold>
  </template>
</body>

提示,<template>自动绑定元素允许我们在主要页面里使用{{}},表达式和on-*来声明事件处理器。

page_total_rows – 每页展示数量 默认值20
$total_rows – 总计数据条目数
$totpages – 总页数计算
$pages_current – 当前页面
利用url参数传递 当前页码 url参数名称 pages
$style – 页码展示样式可以通过外部访问样式属性进行修改
***********************使用方法**********************
调用该类
$pages = new pages;
调用该类后请修改数据集总条数
$pages->total_rows = $totrows;
//$pages->main();方法将返回limit需要的2个参数 关联数组的a,b2个元素
$limit = $pages->main();
通过访问不同方法即可展示不同的功能!
欢迎批评指正 联系qq 5213606
*/
class pages{
public $page_total_rows = 20;//每页展示数量
public $total_rows;//总计数据条目数
public $totpages;//总页数
public $current_url;//当前页面名称
private $ask; //是否出现问号
public $style ='<style
type=”text/css教程”>
.pages_norename{width:50px; height:20px; float:left;
background-color:#e3eff3; margin-right:5px; text-align:center;
line-height:20px; border:1px solid #333333;}
.pages_norename a{display:block; width:50px; height:20px;
color:#333333; text-decoration:none;}
.pages_norename a:hover{background-color:#ff9900; color:#ffffff;}
.pages_nore_more{width:auto; height:20px; float:left;
margin-right:5px; line-height:20px; background-color:#e3eff3;
border:1px solid #333333;}
.pages_nore_more a{display:block; width:20px; height:20px;
color:#333333; text-decoration:none; text-align:center;}
.pages_nore_more a:hover{background-color:#ff9900; color:#ffffff;}
.pages_se{width:auto; height:20px; float:left;}
.pages_se select{margin:0px; padding:0px; font-family:arial, helvetica,
sans-serif; font-size:12px;}
</style>
‘;

键盘导航

键盘支持的重要性不仅仅是为了方便的访问,它同样会使SPA用户刚到更开心。

<core-a11y-keys>是一个标准化浏览器键盘事件的嵌入组件。它可以在你的应用里添加键盘支持。这里有一个例子:

XHTML

<core-a11y-keys target=”{{parentElement}}” keys=”up down left right
space space+shift”
on-keys-pressed=”{{keyHandler}}”></core-a11y-keys>

1
2
3
<core-a11y-keys target="{{parentElement}}"
keys="up down left right space space+shift"
on-keys-pressed="{{keyHandler}}"></core-a11y-keys>

创建“视图”

多视图(或者多页面)可以使用<core-pages>或者<core-animated-pages>来创建。在一次只展示一个子元素时,两个元素都很有用。而使用<core-animated-pages>的好处是,它提供了更多的默认和灵活的页面过渡。

下面的演示(demo)使用了<core-animated-pages>元素的slide-from-right过渡效果。首先,导入元素定义和slide-from-right过渡效果。

XHTML

<link rel=”import”
href=”components/core-animated-pages/core-animated-pages.html”>
<link rel=”import”
href=”components/core-animated-pages/transitions/slide-from-right.html”>

1
2
<link rel="import" href="components/core-animated-pages/core-animated-pages.html">
<link rel="import" href="components/core-animated-pages/transitions/slide-from-right.html">

然后插入你的内容:

XHTML

<div layout horizontal center-center fit> <core-animated-pages
selected=”0″ transitions=”slide-from-right”> <section layout
vertical center-center> <div>Single</div>
</section> <section layout vertical center-center>
<div>page</div> </section> …
</core-animated-pages> </div>

1
2
3
4
5
6
7
8
9
10
11
<div layout horizontal center-center fit>
  <core-animated-pages  selected="0" transitions="slide-from-right">
    <section layout vertical center-center>
      <div>Single</div>
    </section>
    <section layout vertical center-center>
      <div>page</div>
    </section>
    …
  </core-animated-pages>
</div>

注意,现在
<core-animated-pagesselected=”0″>这行代码是硬编码去选择第一页。不过我们以后会把它写成动态的。

现在你应该拥有了一个基本的应用,但是这里有一些小的问题需要注意。多亏了Polymer每个元素提供的布局属性和默认样式,你可以不写任何的CSS代码就可以实现一个响应式应用。当然,从material
design调色板里获取一些灵感,设置不到10
CSS规则就可以让这个应该变得更好看。

展示:没设置CSS 
 
 展示:设置CSS

使用数据绑定

我们拥有了一个应用,但这不值得一提。这离DRY还远着。类似的标记在这里重复出现:

XHTML

<nav> <core-menu selected=”0″> <paper-item noink>
<core-icon icon=”label-outline”></core-icon> <a
href=”#one”>Single</a> </paper-item> <paper-item
noink> <core-icon icon=”label-outline”></core-icon> <a
href=”#two”>page</a> </paper-item> <paper-item
noink> <core-icon icon=”label-outline”></core-icon> <a
href=”#three”>app</a> </paper-item> …
</core-menu> </nav>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<nav>
  <core-menu selected="0">
    <paper-item noink>
      <core-icon icon="label-outline"></core-icon>
      <a href="#one">Single</a>
    </paper-item>
    <paper-item noink>
      <core-icon icon="label-outline"></core-icon>
      <a href="#two">page</a>
    </paper-item>
    <paper-item noink>
      <core-icon icon="label-outline"></core-icon>
      <a href="#three">app</a>
    </paper-item>
    …
  </core-menu>
</nav>

这同样不是动态的。当用户选择一个菜单条目时,页面不会更新。幸运的是,这些问题都可以使用Polymer的数据绑定特性轻松解决。

URL路由(URL routing)和深层链接

<flatiron-director>是一个包装了flatiron director JS
library(一个JS库)的web组件。改变它的route属性把URL#号(URL
hash)更新到相同的值。

当我们想在页面加载时维持上次的视图时,数据绑定再次派上用场。把路由(director.js里的director)、菜单和页面元素连接起来并使它们同步。当一个更新时,其他的同样跟着更新。

XHTML

<flatiron-director route=”{{route}}” autoHash> … <core-menu
selected=”{{route}}”> … <core-animated-pages
selected=”{{route}}”>

1
2
3
4
5
<flatiron-director route="{{route}}" autoHash>
<core-menu selected="{{route}}">
<core-animated-pages selected="{{route}}">

深层链接-当模板准备好时,初始化路由。

XHTML

template.addEventListener(‘template-bound’, function(e) { // Use URL
hash for initial route. Otherwise, use the first page. this.route =
this.route || DEFAULT_ROUTE; };

1
2
3
4
template.addEventListener(‘template-bound’, function(e) {
// Use URL hash for initial route. Otherwise, use the first page.
this.route = this.route || DEFAULT_ROUTE;
};

用Web Components构建单页面应用

2015/01/19 · JavaScript
· Web Components

本文由 伯乐在线 –
周进林
翻译,Mxt
校稿。未经许可,禁止转载!
英文出处:www.polymer-project.org。欢迎加入翻译组。

你是如何使用Polymer构建一个单页应用的?这个问题我们在Polymer团队里已经问过很多遍了。我们的答案(一如既往地)是“使用组件(component)!”。然而,使用新技术去解决现有的问题往往不会马上得到显著的效果。如何把一堆模块化组件组合到一个大型的实用的应用中去?

在本教程,我将会给你展示如何去构建一个功能完整的单页应用:

图片 1

  • 完全使用Polymer的核心元素构建
  • 使用响应式设计
  • 使用数据绑定特性过渡视图
  • 使用URL路由和深层链接特性
  • 可访问键盘
  • 按需动态载入内容(可选)

 打开演示

其他路由库

如果你不喜欢<flatiron-director>,可以试试<app-router>或者<more-routing>。它们都是可以实现更复杂功能的路由(通配符,HTML5历史API,动态内容)。我个人更喜欢<flatiron-director>,因为它简单易用并且可以和<core-animated-pages>很好地配合使用

例子: <more-routing>

XHTML

<more-route-switch> <template when-route=”user”>
<header>User {{params.userId}}</header> <template if=”{{
route(‘user-bio’).active }}”> All the details about
{{params.userId}}. </template> </template> <template
when-route=”/about”> It’s a routing demo! <a _href=”{{
urlFor(‘user-bio’, {userId: 1}) }}”>Read about user 1</a>.
</template> <template else> The index. </template>
</more-route-switch>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<more-route-switch>
  <template when-route="user">
    <header>User {{params.userId}}</header>
    <template if="{{ route(‘user-bio’).active }}">
      All the details about {{params.userId}}.
    </template>
  </template>
  <template when-route="/about">
    It’s a routing demo!
    <a _href="{{ urlFor(‘user-bio’, {userId: 1}) }}">Read about user 1</a>.
  </template>
  <template else>
    The index.
  </template>
</more-route-switch>

例子: <app-router>

XHTML

<app-route path=”/home”
import=”/pages/home-page.html”></app-route> <app-route
path=”/customer/*”
import=”/pages/customer-page.html”></app-route> <app-route
path=”/order/:id” import=”/pages/order-page.html”></app-route>
<app-route path=”*”
import=”/pages/not-found-page.html”></app-route>

1
2
3
4
<app-route path="/home" import="/pages/home-page.html"></app-route>
<app-route path="/customer/*" import="/pages/customer-page.html"></app-route>
<app-route path="/order/:id" import="/pages/order-page.html"></app-route>
<app-route path="*" import="/pages/not-found-page.html"></app-route>

使用数据模型( data model)简化标记

利用数据模型来产生标记可以大量减少你写标记的数量。在我们的案例里,所有的菜单条目和页面都可以利用一对<template
repeat>元素来呈现。

XHTML

<core-menu valueattr=”hash” selected=”{{route}}”> <template
repeat=”{{page in pages}}”> <paper-item hash=”{{page.hash}}”
noink> <core-icon icon=”label-outline”></core-icon> <a
href=”#{{page.hash}}”>{{page.name}}</a> </paper-item>
</template> </core-menu> <core-animated-pages
valueattr=”hash” selected=”{{route}}” transitions=”slide-from-right”>
<template repeat=”{{page in pages}}”> <section
hash=”{{page.hash}}” layout vertical center-center>
<div>{{page.name}}</div> </section> </template>
</core-animated-pages>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<core-menu valueattr="hash" selected="{{route}}">
  <template repeat="{{page in pages}}">
    <paper-item hash="{{page.hash}}" noink>
      <core-icon icon="label-outline"></core-icon>
      <a href="#{{page.hash}}">{{page.name}}</a>
    </paper-item>
  </template>
</core-menu>
 
<core-animated-pages valueattr="hash" selected="{{route}}"
                     transitions="slide-from-right">
  <template repeat="{{page in pages}}">
    <section hash="{{page.hash}}" layout vertical center-center>
      <div>{{page.name}}</div>
    </section>
  </template>
</core-animated-pages>

上面的标记由下面的数据模型来驱动:

XHTML

<script> var template =
document.querySelector(‘template[is=”auto-binding”]’); template.pages
= [ {name: ‘Single’, hash: ‘one’}, {name: ‘page’, hash: ‘two’}, {name:
‘app’, hash: ‘three’}, … ]; </script>

1
2
3
4
5
6
7
8
9
<script>
  var template = document.querySelector(‘template[is="auto-binding"]’);
  template.pages = [
    {name: ‘Single’, hash: ‘one’},
    {name: ‘page’, hash: ‘two’},
    {name: ‘app’, hash: ‘three’},
    …
  ];
</script>

注意,<core-animated-pages>和<core-menu>通过绑定它们的selected属性来关联在一起。现在,当用户点击一个导航条目时,页面会做出相应的更新。valueattr=”hash”设置告诉两个元素在每个条目里使用hash属性作为选择的值。

XHTML

<!– data-bind the menu selection with the page selection –>
<core-menu valueattr=”hash” selected=”{{route}}”> …
<core-animated-pages valueattr=”hash” selected=”{{route}}”>

1
2
3
4
<!– data-bind the menu selection with the page selection –>
<core-menu valueattr="hash" selected="{{route}}">
<core-animated-pages valueattr="hash" selected="{{route}}">

展示

发表评论

电子邮件地址不会被公开。 必填项已用*标注