查询参数
/ / 阅读耗时预计 6 分钟查询参数是在URL的问号(?)右边部分,通常是键值对形式出现。
1 | http://example.com/articles?sort=ASC&page=2 |
比如这个URL的查询参数有两个,一个是sort
,一个是page
,它们的值分别是ASC
和2
。
1,指定查询参数
查询参数通常是声明为controller
类中。比如在当前活动路由articles
下,你需要根据文章的类型category
过滤,此时你必须要在controller
内声明过滤参数category
。
使用Ember CLI新建一个controller
、route
:
1 | ember g controller article; |
1 | // app/controllers/articles.js |
绑定一个查询参数到URL,并且参数的值为null
。当你进入路由articles
时,如果参数category
的值发生变化会自动更新到controller
中的category
;反之亦然。你可以设置一个默认值,比如把category
设置为Java
。可以在模板上获取这个值。
1 | <!-- app/templates/articles.hbs --> |
执行http://localhost:4200/articles,页面会显示出 category = Java
。如果执行http://localhost:4200/articles?category=PHP,那么页面会显示category = PHP
。
下面代码演示了怎么使用查询参数:
1 | // app/controllers/articles.js |
创建一个计算属性,这个计算属性是一个数组类型。由于是计算属性,并且这个计算属性关联了另外两个属性category
和model
,只要这两个属性其中之一发生改变都会导致filteredArticles
发生改变,所以返回的数组元素也会跟着改变。
在route
初始化测试数据。
1 | // app/routes/article.js |
下面看看怎么在模板显示数据,并且根据category
显示不同数据。
1 | <!-- app/templates/articles.hbs --> |
精彩的时刻到了!!先执行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
子表达式直接指定查询参数,需要注意的是这个表达式需要放在括号内使用,切记别少了这个括号。
1 | <!-- app/templates/articles.hbs --> |
在显示数据的ul标签后面新增上述两个link-to
助手。它们的作用分别是指定分类类型为java、php、全部。但用户点击三个连接直接显示与连接指定类型匹配的数据(并且查询的输入框也变为链接指定的类型值)。比如我点击了第一个链接,输入显示如下图:
3,路由转换
route
对象的transitionTo
方法和controller
对象的transitionToRoute
方法都可以接受final
类型的参数。并且这个参数是一个包括一个key
为queryParams
的对象。
修改前面已经创建好的路由posts.js
。
1 | // app/routes/posts.js |
执行http://localhost:4200/posts后,可以看到路由直接跳转到http://localhost:4200/articles?category=java,实现了路由切换的同时也指定了查询的参数。界面显示的数据我就不截图了,程序不出错,显示的都是category
为java
的数据。
另外还有三种切换路由的方式。
1 | // 可以传递一个object过去 |
上面的三种方式请读者自己编写例子试试吧。光看不练假把式⋯⋯
4,选择进入一个完整的路由
transitionTo
和link-to
提供的参数仅会改变查询参数的值,而不会改变路由的层次结构,这种路由的切换被认为是不完整的,这也就意味着比如model
和setupController
回调方法就不会被执行,只是使得controller
里的属性值为新的查询参数值以及更新URL。
但是有些情况是查询参数改变需要从服务器重新加载数据,这种情况就需要一个完整的路由切换了。为了能在查询参数改变的时候切换到一个完整的路由你需要在controller
对应的路由中配置一个名为queryParams
哈希对象。并且需要设置一个名为refreshModel
的查询参数,这个参数的值为true
。
1 | queryParams: { |
关于这段代码演示实例请查看官方提供的代码!
5,使用replaceState更新URL
默认情况下,Ember使用pushState
更新URL来响应controller
类中查询参数属性的变化,但是如果你想使用replaceState
来替换pushState
你可以在route
类中的queryParams
哈希对象中设置replace
为true
。设置为true
表示启用这个设置。
1 | queryParams: { |
6,将控制器的属性映射到不同的查询参数键值
默认情况下,在controller
类中指定的查询属性foo
会绑定到名为foo
的查询参数上。比如:?foo=123
。你也可以把查询属性映射到不同的查询参数上,语法如下:
1 | // app/controllers/articles.js |
这段代码就是把查询属性category
映射到查询参数articles_category
上。
对于有多个查询参数的情况你需要使用数组指定。
1 | // app/controllers/articles.js |
上述代码定义了三个查询参数,如果需要把属性映射到不同名的参数需要手动指定,比如category
。
7,默认值与反序列化
1 | export default Ember.Controller.extend({ |
在这段代码中设置了查询参数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
过滤。如下面的链接:
1 | <ul> |
模板编译之后得到如下HTML代码:
1 | <ul> |
可以看到一旦你改变了查询参数,查询参数就会被存储或者是关联到route
所加载的model
上。如果你想重置查询参数你有如下两种方式处理:
1.在link-to
或者transitionTo
上显式指定查询参数的值;
2.使用Route.resetController
回调设置查询参数的值并回退到切换之前的路由或者是改变model
的路由。
下面的代码片段演示了一个查询参数在controller
中重置为1
,同时作用于切换前ActiclesRoute
的model
。结果就是当返回到当前路由时查询值已经被重置为1
。
1 | // app/routes/article.js |
某些情况下,你不想是用查询参数值限定路由模式,而是让查询参数值改变的时候路由也跟着改变并且会重新加载数据。这时候你可用在对应的controller
类中设置queryParams
哈希对象,在这对象中配置一个参数scope
为controller
。如下:
1 | queryParams: [{ |
粘性的查询参数值这个只是点理解起来好难的说,看下一遍下来都不知道这个有何用!!!现在还是学习阶段还没真正在项目中使用这个特性,所以我也不知道怎么解释更容易理解,建议直接看官网教程吧!!
说明:本文是基于官方2.0参考文档缩写,相对于其他版本内容会有出入。
以上的内容就是有关查询参数的全部了,主要是理解了查询参数的设置使用起来也就没什么问题。有点遗憾的是没能写出第4点的演示实例!能力有限只能遇到或者明白其使用的时候再补上了!!
博文完整代码放在[Github](https://github.com/ubuntuvim/my_emberjs_code)(博文经过多次修改,博文上的代码与github代码可能又出入,不过影响不大!),如果你觉得博文对你有点用,请在github项目上给我点个`star`吧。您的肯定对我来说是最大的动力!!