Ember.js 入门指南——查询参数
2015-09-30 00:30
886 查看
查询参数是在URL的问号(?)右边部分,通常是键值对形式出现。
比如这个URL的查询参数有两个,一个是sort,一个是page,它们的值分别是ASC和2。
查询参数通常是声明为controller类中。比如在当前活动路由articles下,你需要根据文章的类型category过滤,此时你必须要在controller内声明过滤参数category。
使用Ember CLI新建一个controller、route:
ember g controller article;
ember g route articles;
绑定一个查询参数到URL,并且参数的值为null。当你进入路由articles时,如果参数category的值发生变化会自动更新到controller中的category;反之亦然。你可以设置一个默认值,比如把category设置为“Java”。可以在模板上获取这个值。
执行http://localhost:4200/articles,页面会显示出 category = Java。如果执行http://localhost:4200/articles?category=PHP,那么页面会显示category
= PHP。
下面代码演示了怎么使用查询参数:
创建一个计算属性,这个计算属性是一个数组类型。由于是计算属性,并且这个计算属性关联了另外两个属性category和model,只要这两个属性其中之一发生改变都会导致filteredArticles发生改变,所以返回的数组元素也会跟着改变。
在route初始化测试数据。
下面看看怎么在模板显示数据,并且根据category显示不同数据。
精彩的时刻到了!!先执行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:”,也有可能是我看不懂,反正摸索好一阵子才知道要这么用!!
link-to助手使用query-params子表达式直接指定查询参数,需要注意的是这个表达式需要放在括号内使用,切记别少了这个括号。
在显示数据的ul标签后面新增上述两个link-to助手。它们的作用分别是指定分类类型为java、php、全部。但用户点击三个连接直接显示与连接指定类型匹配的数据(并且查询的输入框也变为链接指定的类型值)。比如我点击了第一个链接,输入显示如下图:
route对象的transitionTo方法和controller对象的transitionToRoute方法都可以接受final类型的参数。并且这个参数是一个包括一个key为queryParams的对象。
修改前面已经创建好的路由posts.js。
执行http://localhost:4200/posts后,可以看到路由直接跳转到http://localhost:4200/articles?category=java,实现了路由切换的同时也指定了查询的参数。界面显示的数据我就不截图了,程序不出错,显示的都是category为java的数据。
另外还有三种切换路由的方式。
上面的三种方式请读者自己编写例子试试吧。光看不练假把式……
transitionTo和link-to提供的参数仅会改变查询参数的值,而不会改变路由的层次结构,这种路由的切换被认为是不完整的,这也就意味着比如model和setupController回调方法就不会被执行,只是使得controller里的属性值为新的查询参数值以及更新URL。
但是有些情况是查询参数改变需要从服务器重新加载数据,这种情况就需要一个完整的路由切换了。为了能在查询参数改变的时候切换到一个完整的路由你需要在controller对应的路由中配置一个名为queryParams哈希对象。并且需要设置一个名为refreshModel的查询参数,这个参数的值为true。
关于这段代码演示实例请查看官方提供的代码!
默认情况下,Ember使用pushState更新URL来响应controller类中查询参数属性的变化,但是如果你想使用replaceState来替换pushState你可以在route类中的queryParams哈希对象中设置replace为true。设置为true表示启用这个设置。
默认情况下,在controller类中指定的查询属性foo会绑定到名为foo的查询参数上。比如:?foo=123。你也可以把查询属性映射到不同的查询参数上,语法如下:
这段代码就是把查询属性category映射到查询参数articles_category上。
对于有多个查询参数的情况你需要使用数组指定。
上述代码定义了三个查询参数,如果需要把属性映射到不同名的参数需要手动指定,比如category。
在这段代码中设置了查询参数page的默认值为1。
这样的设置会有两种默认的行为:
查询的时候查询属性值会根据默认值的类型自动转换,所以当用户输入http://localhost:4200/articles?page=1的时候page的值1会被识别成数字1而不是字符’1’,应为设置的默认值1是数字类型。
当查询的值正好是默认值的时候,该值不会被序列化到URL中。比如查询值正好是“?page=1”这种情况URL可能是“/articles”,但是如果查询值是“?page=2”,URL肯定是“/articles?page=2”。
默认情况下,在Ember中查询参数是“粘性的”,也就是说如果你改变了查询参数或者是离开页面又回退回来,新的查询值会默认在URL上,而不会自动清除(几乎所见的URL都差不多是这种情况)。这是个很有用的默认设置,特别是当你点击后退回到原页面的时候显示的数据没有改变。
此外,粘性的查询参数值会被加载的route存储或者回复。比如,包括了动态段“/:post_id”的路由posts,以及路由对应的controller包含了查询属性“filter”。如果你导航到/badgers并且根据reookies过滤,然后再导航到/bears并根据best过滤,然后再导航到/potatose并根据lamest过滤。如下面的链接:
模板编译之后得到如下HTML代码:
可以看到一旦你改变了查询参数,查询参数就会被存储或者是关联到route所加载的model上。如果你想重置查询参数你有如下两种方式处理:
在link-to或者transitionTo上显式指定查询参数的值;
使用Route.resetController回调设置查询参数的值并回退到切换之前的路由或者是改变model的路由。
下面的代码片段演示了一个查询参数在controller中重置为1,同时作用于切换前ActiclesRoute的model。结果就是当返回到当前路由时查询值已经被重置为1。
某些情况下,你不想是用查询参数值限定路由模式,而是让查询参数值改变的时候路由也跟着改变并且会重新加载数据。这时候你可用在对应的controller类中设置queryParams哈希对象,在这对象中配置一个参数scope为controller。如下:
粘性的查询参数值这个只是点理解起来好难的说,看下一遍下来都不知道这个有何用!!!现在还是学习阶段还没真正在项目中使用这个特性,所以我也不知道怎么解释更容易理解,建议直接看官网教程吧!!
官方提供的示例:
· 查询
· 排序: 客户端,不重新触发模型钩子
· 排序: 服务器端,重新触发模型钩子
· 分页和排序
· 布尔值
· 在应用路由中的全局查询参数
· 通过设置refreshModel:true实现完整过渡
· 通过设置replace:true实现replaceState
· 易实现标签的w/
{{partial}}助手
· 不带路由名只有查询参数的link-to
· 合成:序列化多行文本输入框内容到URL(子表达式)
· 数组
· 使用冒号语法映射不同的URL键值
以上的内容就是有关查询参数的全部了,主要是理解了查询参数的设置使用起来也就没什么问题。有点遗憾的是没能写出第4点的演示实例!能力有限只能遇到或者明白其使用的时候再补上了!!
http://example.com/articles?sort=ASC&page=2
比如这个URL的查询参数有两个,一个是sort,一个是page,它们的值分别是ASC和2。
1,指定查询参数
查询参数通常是声明为controller类中。比如在当前活动路由articles下,你需要根据文章的类型category过滤,此时你必须要在controller内声明过滤参数category。使用Ember CLI新建一个controller、route:
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/templates/articles.hbs --> {{outlet}}category = {{category}}
执行http://localhost:4200/articles,页面会显示出 category = Java。如果执行http://localhost:4200/articles?category=PHP,那么页面会显示category
= PHP。
下面代码演示了怎么使用查询参数:
// 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; } }) });
创建一个计算属性,这个计算属性是一个数组类型。由于是计算属性,并且这个计算属性关联了另外两个属性category和model,只要这两个属性其中之一发生改变都会导致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助手。它们的作用分别是指定分类类型为java、php、全部。但用户点击三个连接直接显示与连接指定类型匹配的数据(并且查询的输入框也变为链接指定的类型值)。比如我点击了第一个链接,输入显示如下图:
3,路由切换
route对象的transitionTo方法和controller对象的transitionToRoute方法都可以接受final类型的参数。并且这个参数是一个包括一个key为queryParams的对象。修改前面已经创建好的路由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,实现了路由切换的同时也指定了查询的参数。界面显示的数据我就不截图了,程序不出错,显示的都是category为java的数据。
另外还有三种切换路由的方式。
// 可以传递一个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,选择进入一个完整的路由
transitionTo和link-to提供的参数仅会改变查询参数的值,而不会改变路由的层次结构,这种路由的切换被认为是不完整的,这也就意味着比如model和setupController回调方法就不会被执行,只是使得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哈希对象中设置replace为true。设置为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。
这样的设置会有两种默认的行为:
查询的时候查询属性值会根据默认值的类型自动转换,所以当用户输入http://localhost:4200/articles?page=1的时候page的值1会被识别成数字1而不是字符’1’,应为设置的默认值1是数字类型。
当查询的值正好是默认值的时候,该值不会被序列化到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上。如果你想重置查询参数你有如下两种方式处理:
在link-to或者transitionTo上显式指定查询参数的值;
使用Route.resetController回调设置查询参数的值并回退到切换之前的路由或者是改变model的路由。
下面的代码片段演示了一个查询参数在controller中重置为1,同时作用于切换前ActiclesRoute的model。结果就是当返回到当前路由时查询值已经被重置为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哈希对象,在这对象中配置一个参数scope为controller。如下:
queryParams: [{ showMagnifyingGlass: { scope: 'controller' } }]
粘性的查询参数值这个只是点理解起来好难的说,看下一遍下来都不知道这个有何用!!!现在还是学习阶段还没真正在项目中使用这个特性,所以我也不知道怎么解释更容易理解,建议直接看官网教程吧!!
官方提供的示例:
· 查询
· 排序: 客户端,不重新触发模型钩子
· 排序: 服务器端,重新触发模型钩子
· 分页和排序
· 布尔值
· 在应用路由中的全局查询参数
· 通过设置refreshModel:true实现完整过渡
· 通过设置replace:true实现replaceState
· 易实现标签的w/
{{partial}}助手
· 不带路由名只有查询参数的link-to
· 合成:序列化多行文本输入框内容到URL(子表达式)
· 数组
· 使用冒号语法映射不同的URL键值
以上的内容就是有关查询参数的全部了,主要是理解了查询参数的设置使用起来也就没什么问题。有点遗憾的是没能写出第4点的演示实例!能力有限只能遇到或者明白其使用的时候再补上了!!
相关文章推荐
- JQuery1——基础($对象,选择器,对象转换)
- Android学习笔记(二九):嵌入浏览器
- Android java 与 javascript互访(相互调用)的方法例子
- JavaScript演示排序算法
- javascript实现10进制转为N进制数
- 2019年开发人员应该学习的8个JavaScript框架
- HTML中的script标签研究
- 对一个分号引发的错误研究
- 异步流程控制:7 行代码学会 co 模块
- ES6 走马观花(ECMAScript2015 新特性)
- JavaScript拆分字符串时产生空字符的原因
- Canvas 在高清屏下绘制图片变模糊的解决方法
- IE8开发人员工具教程(二)
- 在flex中执行一个javascript方法的简单方式
- Flex结合JavaScript读取本地路径的方法
- PowerShell中执行Javascript的方法示例
- javascript asp教程第六课-- response方法
- javascript asp教程More About Recordsets
- javascript asp教程第十二课---session对象