查詢參數(shù)是在URL的問號(?)右邊部分,通常是鍵值對形式出現(xiàn)。
http://example.com/articles?sort=ASC&page=2
比如這個URL的查詢參數(shù)有兩個,一個是sort
,一個是page
,它們的值分別是ASC
和2
。
查詢參數(shù)通常是聲明為controller
類中。比如在當前活動路由articles
下,你需要根據(jù)文章的類型category
過濾,此時你必須要在controller
內(nèi)聲明過濾參數(shù)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
});
綁定一個查詢參數(shù)到URL,并且參數(shù)的值為null
。當你進入路由articles
時,如果參數(shù)category
的值發(fā)生變化會自動更新到controller
中的category
;反之亦然。你可以設置一個默認值,比如把category
設置為Java
??梢栽谀0迳汐@取這個值。
{{outlet}}
category = {{category}}
執(zhí)行http://localhost:4200/articles,頁面會顯示出 category = Java
。如果執(zhí)行http://localhost:4200/articles?category=PHP,那么頁面會顯示category = PHP
。
下面代碼演示了怎么使用查詢參數(shù):
// app/controllers/articles.js
import Ember from 'ember';
export default Ember.Controller.extend({
queryParams: ['category'],
category: null,
// 定義一個返回數(shù)組的計算屬性,可以直接在模板上遍歷
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;
}
})
});
創(chuàng)建一個計算屬性,這個計算屬性是一個數(shù)組類型。由于是計算屬性,并且這個計算屬性關(guān)聯(lián)了另外兩個屬性category
和model
,只要這兩個屬性其中之一發(fā)生改變都會導致filteredArticles
發(fā)生改變,所以返回的數(shù)組元素也會跟著改變。
在route
初始化測試數(shù)據(jù)。
// 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' }
];
}
});
下面看看怎么在模板顯示數(shù)據(jù),并且根據(jù)category
顯示不同數(shù)據(jù)。
<div class="col-md-4 col-xs-4">
<ul>
輸入分類:{{input value=category placeholder ='查詢的分類'}}
</ul>
<ul>
{{#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>
精彩的時刻到了??!先執(zhí)行http://localhost:4200/articles,此時顯示的是所有類型的數(shù)據(jù)。如下圖:
接著你就可以做點好玩的事了,直接在輸入框輸入分類名。由于計算屬性的特性會自動更新數(shù)組filteredArticles
。所以我們可以看到隨著你輸入字符的變化顯示的數(shù)據(jù)也在變化!這個例子也說明了Ember計算屬性自動更新變化的強大??!用著確實爽啊??!
官網(wǎng)教程沒有說怎么在模板中使用,講得也不是很明白,就給了一句
Now we just need to define a computed property of our category-filtered array that the articles template will render:”
也有可能是我看不懂,反正摸索好一陣子才知道要這么用??!
link-to
助手使用query-params
子表達式直接指定查詢參數(shù),需要注意的是這個表達式需要放在括號內(nèi)使用,切記別少了這個括號。
……
<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>
……
在顯示數(shù)據(jù)的ul標簽后面新增上述兩個link-to
助手。它們的作用分別是指定分類類型為java、php、全部。但用戶點擊三個連接直接顯示與連接指定類型匹配的數(shù)據(jù)(并且查詢的輸入框也變?yōu)殒溄又付ǖ念愋椭担?。比如我點擊了第一個鏈接,輸入顯示如下圖:
route
對象的transitionTo
方法和controller
對象的transitionToRoute
方法都可以接受final
類型的參數(shù)。并且這個參數(shù)是一個包括一個key
為queryParams
的對象。
修改前面已經(jīng)創(chuàng)建好的路由posts.js
。
// app/routes/posts.js
import Ember from 'ember';
export default Ember.Route.extend({
beforeModel: function(params) {
// 轉(zhuǎn)到路由articles上,并且傳遞查詢參數(shù)category,參數(shù)值為Java
this.transitionTo('articles', { queryParams: { category: 'java' }});
}
});
執(zhí)行http://localhost:4200/posts后,可以看到路由直接跳轉(zhuǎn)到http://localhost:4200/articles?category=java,實現(xiàn)了路由切換的同時也指定了查詢的參數(shù)。界面顯示的數(shù)據(jù)我就不截圖了,程序不出錯,顯示的都是category
為java
的數(shù)據(jù)。
另外還有三種切換路由的方式。
// 可以傳遞一個object過去
this.transitionTo('articles', object, { queryParams: { category: 'java' }});
// 這種方式不會改變路由,只是起到設置參數(shù)的作用,如果你在
//路由articles中使用這個方法,你的路由仍然是articles,只是查詢參數(shù)變了。
this.transitionTo({ queryParams: { direction: 'asc' }});
// 直接指定跳轉(zhuǎn)的URL和查詢參數(shù)
this.transitionTo('/posts/1?sort=date&showDetails=true');
上面的三種方式請讀者自己編寫例子試試吧。光看不練假把式……
transitionTo
和link-to
提供的參數(shù)僅會改變查詢參數(shù)的值,而不會改變路由的層次結(jié)構(gòu),這種路由的切換被認為是不完整的,這也就意味著比如model
和setupController
回調(diào)方法就不會被執(zhí)行,只是使得controller
里的屬性值為新的查詢參數(shù)值以及更新URL。
但是有些情況是查詢參數(shù)改變需要從服務器重新加載數(shù)據(jù),這種情況就需要一個完整的路由切換了。為了能在查詢參數(shù)改變的時候切換到一個完整的路由你需要在controller
對應的路由中配置一個名為queryParams
哈希對象。并且需要設置一個名為refreshModel
的查詢參數(shù),這個參數(shù)的值為true
。
queryParams: {
category: {
refreshModel: true
}
},
model: function(params) {
return this.store.query('article', params);
}
關(guān)于這段代碼演示實例請查看官方提供的代碼!
默認情況下,Ember使用pushState
更新URL來響應controller
類中查詢參數(shù)屬性的變化,但是如果你想使用replaceState
來替換pushState
你可以在route
類中的queryParams
哈希對象中設置replace
為true
。設置為true
表示啟用這個設置。
queryParams: {
category: {
replaceState:true
}
}
默認情況下,在controller
類中指定的查詢屬性foo
會綁定到名為foo
的查詢參數(shù)上。比如:?foo=123
。你也可以把查詢屬性映射到不同的查詢參數(shù)上,語法如下:
// app/controllers/articles.js
import Ember from 'ember';
export default Ember.Controller.extend({
queryParams: {
category: 'articles_category'
}
category: null
});
這段代碼就是把查詢屬性category
映射到查詢參數(shù)articles_category
上。
對于有多個查詢參數(shù)的情況你需要使用數(shù)組指定。
// 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'
});
上述代碼定義了三個查詢參數(shù),如果需要把屬性映射到不同名的參數(shù)需要手動指定,比如category
。
export default Ember.Controller.extend({
queryParams: 'page',
page: 1
});
在這段代碼中設置了查詢參數(shù)page
的默認值為1
。
這樣的設置會有兩種默認的行為:
1.查詢的時候查詢屬性值會根據(jù)默認值的類型自動轉(zhuǎn)換,所以當用戶輸入http://localhost:4200/articles?page=1的時候page
的值1
會被識別成數(shù)字1
而不是字符'1'
,應為設置的默認值1
是數(shù)字類型。
2.當查詢的值正好是默認值的時候,該值不會被序列化到URL中。比如查詢值正好是?page=1
這種情況URL可能是/articles
,但是如果查詢值是?page=2
,URL肯定是/articles?page=2
。
默認情況下,在Ember中查詢參數(shù)是“粘性的”,也就是說如果你改變了查詢參數(shù)或者是離開頁面又回退回來,新的查詢值會默認在URL上,而不會自動清除(幾乎所見的URL都差不多是這種情況)。這是個很有用的默認設置,特別是當你點擊后退回到原頁面的時候顯示的數(shù)據(jù)沒有改變。
此外,粘性的查詢參數(shù)值會被加載的route
存儲或者回復。比如,包括了動態(tài)段/:post_id
的路由posts
,以及路由對應的controller
包含了查詢屬性filter
。如果你導航到/badgers
并且根據(jù)reookies
過濾,然后再導航到/bears
并根據(jù)best
過濾,然后再導航到/potatose
并根據(jù)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>
可以看到一旦你改變了查詢參數(shù),查詢參數(shù)就會被存儲或者是關(guān)聯(lián)到route
所加載的model
上。如果你想重置查詢參數(shù)你有如下兩種方式處理:
1.在link-to
或者transitionTo
上顯式指定查詢參數(shù)的值;
2.使用Route.resetController
回調(diào)設置查詢參數(shù)的值并回退到切換之前的路由或者是改變model
的路由。
下面的代碼片段演示了一個查詢參數(shù)在controller
中重置為1
,同時作用于切換前ActiclesRoute
的model
。結(jié)果就是當返回到當前路由時查詢值已經(jīng)被重置為1
。
// app/routes/article.js
import Ember from 'ember';
export default Ember.Route.extend({
resetController(controller, isExiting, transition) {
// 只有model發(fā)生變化的時候isExiting才為false
if (isExiting) {
// 重置查詢屬性的值
controller.set('page', 1);
}
}
});
某些情況下,你不想是用查詢參數(shù)值限定路由模式,而是讓查詢參數(shù)值改變的時候路由也跟著改變并且會重新加載數(shù)據(jù)。這時候你可用在對應的controller
類中設置queryParams
哈希對象,在這對象中配置一個參數(shù)scope
為controller
。如下:
queryParams: [{
showMagnifyingGlass: {
scope: 'controller'
}
}]
粘性的查詢參數(shù)值這個只是點理解起來好難的說,看下一遍下來都不知道這個有何用?。。‖F(xiàn)在還是學習階段還沒真正在項目中使用這個特性,所以我也不知道怎么解釋更容易理解,建議直接看官網(wǎng)教程吧!!
說明:本文是基于官方2.0參考文檔縮寫,相對于其他版本內(nèi)容會有出入。
以上的內(nèi)容就是有關(guān)查詢參數(shù)的全部了,主要是理解了查詢參數(shù)的設置使用起來也就沒什么問題。有點遺憾的是沒能寫出第4點的演示實例!能力有限只能遇到或者明白其使用的時候再補上了!!
博文完整代碼放在Github(博文經(jīng)過多次修改,博文上的代碼與github代碼可能又出入,不過影響不大?。?,如果你覺得博文對你有點用,請在github項目上給我點個star
吧。您的肯定對我來說是最大的動力!!
更多建議: