查詢參數是在URL的問號(?)右邊部分,一般是鍵值對形式出現。 php
http://example.com/articles?sort=ASC&page=2
好比這個URL的查詢參數有兩個,一個是sort,一個是page,它們的值分別是ASC和2。html
查詢參數一般是聲明爲controller類中。好比在當前活動路由articles下,你須要根據文章的類型category過濾,此時你必需要在controller內聲明過濾參數category。java
使用Ember CLI新建一個controller、route:json
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 = PHP。ide
下面代碼演示了怎麼使用查詢參數: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; } }) });
建立一個計算屬性,這個計算屬性是一個數組類型。因爲是計算屬性,而且這個計算屬性關聯了另外兩個屬性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:」,也有多是我看不懂,反正摸索好一陣子才知道要這麼用!!
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、所有。但用戶點擊三個鏈接直接顯示與鏈接指定類型匹配的數據(而且查詢的輸入框也變爲連接指定的類型值)。好比我點擊了第一個連接,輸入顯示以下圖:
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');
上面的三種方式請讀者本身編寫例子試試吧。光看不練假把式……
transitionTo和link-to提供的參數僅會改變查詢參數的值,而不會改變路由的層次結構,這種路由的切換被認爲是不完整的,這也就意味着好比model和setupController回調方法就不會被執行,只是使得controller裏的屬性值爲新的查詢參數值以及更新URL。
可是有些狀況是查詢參數改變須要從服務器從新加載數據,這種狀況就須要一個完整的路由切換了。爲了能在查詢參數改變的時候切換到一個完整的路由你須要在controller對應的路由中配置一個名爲queryParams哈希對象。而且須要設置一個名爲refreshModel的查詢參數,這個參數的值爲true。
queryParams: { category: { refreshModel: true } }, model: function(params) { return this.store.query('article', params); }
關於這段代碼演示實例請查看官方提供的代碼!
默認狀況下,Ember使用pushState更新URL來響應controller類中查詢參數屬性的變化,可是若是你想使用replaceState來替換pushState你能夠在route類中的queryParams哈希對象中設置replace爲true。設置爲true表示啓用這個設置。
queryParams: { category: { replaceState:true } }
默認狀況下,在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。
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」。
默認狀況下,在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' } }]
粘性的查詢參數值這個只是點理解起來好難的說,看下一遍下來都不知道這個有何用!!!如今仍是學習階段還沒真正在項目中使用這個特性,因此我也不知道怎麼解釋更容易理解,建議直接看官網教程吧!!
官方提供的示例:
· 查詢
· 分頁和排序
· 布爾值
· 通過設置replace:true實現replaceState
· 數組
以上的內容就是有關查詢參數的所有了,主要是理解了查詢參數的設置使用起來也就沒什麼問題。有點遺憾的是沒能寫出第4點的演示實例!能力有限只能遇到或者明白其使用的時候再補上了!!