Ember.js 入门指南——查询参数

查询参数是在URL的问号(?)右边部分,一般是键值对形式出现。 php

http://example.com/articles?sort=ASC&page=2

       好比这个URL的查询参数有两个,一个是sort,一个是page,它们的值分别是ASC2html

 

1,指定查询参数      

       查询参数一般是声明为controller类中。好比在当前活动路由articles下,你须要根据文章的类型category过滤,此时你必需要在controller内声明过滤参数categoryjava

使用Ember CLI新建一个controllerroutejson

ember g controller article数组

ember g route articles;服务器

//  app/controllers/articles.js
 
import Ember from 'ember';
 
export default Ember.Controller.extend({
       queryParams: ['category'],
       category: null
});

    绑定一个查询参数到URL,而且参数的值为null。当你进入路由articles时,若是参数category的值发生变化会自动更新到controller中的category;反之亦然。你能够设置一个默认值,好比把category设置为“Java”。能够在模板上获取这个值。app

<!--    app/templates/articles.hbs    -->
{{outlet}}category = {{category}}

执行http://localhost:4200/articles,页面会显示出   category = Java。若是执行http://localhost:4200/articles?category=PHP,那么页面会显示category = PHPide

       下面代码演示了怎么使用查询参数:post

//  app/controllers/articles.js
 
import Ember from 'ember';
 
export default Ember.Controller.extend({
    queryParams: ['category'],
    category: null,
 
    //  定义一个返回数组的计算属性,能够直接在模板上遍历
    filteredArticles: Ember.computed('category', 'model', function() {
           var category = this.get('category');
           var articles = this.get('model');
 
           if (category) {
               return articles.filterBy('category', category);
           } else {
               return articles;
           }
    })
});

       建立一个计算属性,这个计算属性是一个数组类型。因为是计算属性,而且这个计算属性关联了另外两个属性categorymodel,只要这两个属性其中之一发生改变都会致使filteredArticles发生改变,因此返回的数组元素也会跟着改变。学习

       route初始化测试数据。

//  app/routes/article.js
 
import Ember from 'ember';
 
export default Ember.Route.extend({
 
    model(params) {
          
           return [
                 { id: 1, title: 'Bower: dependencies and resolutions new', body: "In the bower.json file, I see 2 keys dependencies and resolutionsWhy is that so? I understand Bower has a flat dependency structure. So has it got anything to do with that ?", category: 'java' },
                 { id: 2, title: 'Highly Nested JSON Payload - hasMany error', body: "Welcome to the Ember.js discussion forum. We're running on the open source, Ember.js-powered Discourse forum software. They are also providing the hosting for us. Thanks guys! Please use this space for discussion abo… read more", category: 'php' },
                 { id: 3, title: 'Passing a jwt to my REST adapter new ', body: "This sets up a binding between the category query param in the URL, and the category property on controller:articles. In other words, once the articles route has been entered, any changes to the category query param in the URL will update the category property on controller:articles, and vice versa.", category: 'java' }
           ];
    }
});

 

下面看看怎么在模板显示数据,而且根据category显示不一样数据。

<!--  app/templates/articles.hbs  -->
 
<div class="col-md-4 col-xs-4">
 
<ul>
    <!-- 输入的值会动态更新到controller  -->
       输入分类:{{input value=category placeholder ='查询的分类'}}
</ul>
 
<ul>
       <!-- 关键点:这里使用的是filteredArticles而不是从route获取的model -->
       {{#each filteredArticles as |item|}}
              <li>
                     {{#link-to 'articles.article' item}} {{item.title}}--{{item.category}} {{/link-to}}
              </li>     
       {{/each}}
</ul>
 
</div>
 
<div class="col-md-8 col-xs-8">
{{outlet}}
</div>

       精彩的时刻到了!!先执行http://localhost:4200/articles,此时显示的是全部类型的数据。以下图:

接着你就能够作点好玩的事了,直接在输入框输入分类名。因为计算属性的特性会自动更新数组filteredArticles。因此咱们能够看到随着你输入字符的变化显示的数据也在变化!这个例子也说明了Ember计算属性自动更新变化的强大!!用着确实爽啊!!

官网教程没有说怎么在模板中使用,讲得也不是很明白,就给了一句“Now we just need to define a computed property of our category-filtered array that the articles template will render:”,也有多是我看不懂,反正摸索好一阵子才知道要这么用!!

2使用link-to指定查询参数    

       link-to助手使用query-params子表达式直接指定查询参数,须要注意的是这个表达式须要放在括号内使用,切记别少了这个括号。

<!--  app/templates/articles.hbs  -->
……
<ul>
       {{#link-to 'articles' (query-params category='java')}} java {{/link-to}}
       <br>
       {{#link-to 'articles' (query-params category='php')}} php {{/link-to}}
       <br>
       {{#link-to 'articles' (query-params category='')}} all {{/link-to}}
</ul>
……

       在显示数据的ul标签后面新增上述两个link-to助手。它们的做用分别是指定分类类型为javaphp、所有。但用户点击三个链接直接显示与链接指定类型匹配的数据(而且查询的输入框也变为连接指定的类型值)。好比我点击了第一个连接,输入显示以下图:

3路由切换 

       route对象的transitionTo方法和controller对象的transitionToRoute方法均可以接受final类型的参数。而且这个参数是一个包括一个keyqueryParams的对象。

       修改前面已经建立好的路由posts.js

//  app/routes/posts.js
import Ember from 'ember';
export default Ember.Route.extend({
 
       beforeModel: function(params) {
 
              //  转到路由articles上,而且传递查询参数category,参数值为Java
              this.transitionTo('articles', { queryParams: { category: 'java' }});
       }
});

       执行http://localhost:4200/posts后,能够看到路由直接跳转到http://localhost:4200/articles?category=java,实现了路由切换的同时也指定了查询的参数。界面显示的数据我就不截图了,程序不出错,显示的都是categoryjava的数据。

       另外还有三种切换路由的方式。

//  能够传递一个object过去
this.transitionTo('articles', object, { queryParams: { category: 'java' }});
 
// 这种方式不会改变路由,只是起到设置参数的做用,若是你在
//路由articles中使用这个方法,你的路由仍然是articles,只是查询参数变了。
this.transitionTo({ queryParams: { direction: 'asc' }});
 
//  直接指定跳转的URL和查询参数
this.transitionTo('/posts/1?sort=date&showDetails=true');

       上面的三种方式请读者本身编写例子试试吧。光看不练假把式……

 

4选择进入一个完整的路由    

       transitionTolink-to提供的参数仅会改变查询参数的值,而不会改变路由的层次结构,这种路由的切换被认为是不完整的,这也就意味着好比modelsetupController回调方法就不会被执行,只是使得controller里的属性值为新的查询参数值以及更新URL

       可是有些状况是查询参数改变须要从服务器从新加载数据,这种状况就须要一个完整的路由切换了。为了能在查询参数改变的时候切换到一个完整的路由你须要在controller对应的路由中配置一个名为queryParams哈希对象。而且须要设置一个名为refreshModel的查询参数,这个参数的值为true

queryParams: {
       category: {
              refreshModel: true
       }
},
model: function(params) {
    return this.store.query('article', params);
}

      关于这段代码演示实例请查看官方提供的代码 


5,使用replaceState更新URL

       默认状况下,Ember使用pushState更新URL来响应controller类中查询参数属性的变化,可是若是你想使用replaceState来替换pushState你能够在route类中的queryParams哈希对象中设置replacetrue。设置为true表示启用这个设置。

queryParams: {
    category: {
        replaceState:true
    }
}

 

6,将控制器的属性映射到不一样的查询参数键值

       默认状况下,在controller类中指定的查询属性foo会绑定到名为foo的查询参数上。好比:?foo=123。你也能够把查询属性映射到不一样的查询参数上,语法以下:

//  app/controllers/articles.js
import Ember from 'ember';
export default Ember.Controller.extend({
    queryParams: {
          category: 'articles_category'
    }
    category: null
});

       这段代码就是把查询属性category映射到查询参数articles_category上。

对于有多个查询参数的状况你须要使用数组指定。

//  app/controllers/articles.js
import Ember from 'ember';
export default Ember.Controller.extend({
       queryParams: ['page', 'filter', { category: 'articles_category' }],
    category: null,
    page: 1,
    filter: 'recent'
});

       上述代码定义了三个查询参数,若是须要把属性映射到不一样名的参数须要手动指定,好比category

7,默认值与反序列化

export default Ember.Controller.extend({
    queryParams: 'page',
    page: 1
});

       在这段代码中设置了查询参数page的默认值为1

       这样的设置会有两种默认的行为:

  1. 查询的时候查询属性值会根据默认值的类型自动转换,因此当用户输入http://localhost:4200/articles?page=1的时候page的值1会被识别成数字1而不是字符’1’,应为设置的默认值1是数字类型。

  2. 当查询的值正好是默认值的时候,该值不会被序列化到URL中。好比查询值正好是?page=1这种状况URL多是“/articles”,可是若是查询值是“?page=2”URL确定是“/articles?page=2”

 

8,粘性的查询参数值

       默认状况下,在Ember中查询参数是粘性的,也就是说若是你改变了查询参数或者是离开页面又回退回来,新的查询值会默认在URL上,而不会自动清除(几乎所见的URL都差很少是这种状况)。这是个颇有用的默认设置,特别是当你点击后退回到原页面的时候显示的数据没有改变。    

       此外,粘性的查询参数值会被加载的route存储或者回复。好比,包括了动态段“/:post_id”的路由posts,以及路由对应的controller包含了查询属性“filter”。若是你导航到/badgers而且根据reookies过滤,而后再导航到/bears并根据best过滤,而后再导航到/potatose并根据lamest过滤。以下面的连接:

<ul>
       {{#link-to 'posts' 'badgers'}}Badgers{{/link-to}}<br>
       {{#link-to 'posts' 'bears'}}Bears{{/link-to}}<br>
       {{#link-to 'posts' 'potatoes'}}Potatoes{{/link-to}}<br>
</ul>

模板编译以后获得以下HTML代码:

<ul>
    <a href="/badgers?filter=rookies">Badgers</a>
    <a href="/bears?filter=best">Bears</a>
    <a href="/potatoes?filter=lamest">Potatoes</a>
</ul>

       能够看到一旦你改变了查询参数,查询参数就会被存储或者是关联到route所加载的model上。若是你想重置查询参数你有以下两种方式处理:

  1. link-to或者transitionTo上显式指定查询参数的值;

  2. 使用Route.resetController回调设置查询参数的值并回退到切换以前的路由或者是改变model的路由。

下面的代码片断演示了一个查询参数在controller中重置为1,同时做用于切换前ActiclesRoutemodel。结果就是当返回到当前路由时查询值已经被重置为1

//  app/routes/article.js
 
import Ember from 'ember';
 
export default Ember.Route.extend({
 
       resetController(controller, isExiting, transition) {
              //  只有model发生变化的时候isExiting才为false
              if (isExiting) {
                     //  重置查询属性的值
                     controller.set('page', 1);
              }
       }
});

 

某些状况下,你不想是用查询参数值限定路由模式,而是让查询参数值改变的时候路由也跟着改变而且会从新加载数据。这时候你可用在对应的controller类中设置queryParams哈希对象,在这对象中配置一个参数scopecontroller。以下:

queryParams: [{
    showMagnifyingGlass: {
              scope: 'controller'
       }
}]

       粘性的查询参数值这个只是点理解起来好难的说,看下一遍下来都不知道这个有何用!!!如今仍是学习阶段还没真正在项目中使用这个特性,因此我也不知道怎么解释更容易理解,建议直接看官网教程吧!!

官方提供的示例:

·       查询

·       排序: 端,不从新触模型

·       排序: 器端,从新触模型

·       和排序

·       尔值

·       用路由中的全局查询参数

·       过设refreshModel:true实现完整过渡

·       过设replace:true实现replaceState

·       实现标签w/ {{partial}}助手

·       路由名只有查询参数的link-to

·       合成:序列化多行文本入框内容到URL(子表达式)

·      

·       使用冒号法映射不一样的URL键值

 

以上的内容就是有关查询参数的所有了,主要是理解了查询参数的设置使用起来也就没什么问题。有点遗憾的是没能写出第4点的演示实例!能力有限只能遇到或者明白其使用的时候再补上了!!

相关文章
相关标签/搜索