Ember 查詢參數(shù)

2018-01-06 17:50 更新

查詢參數(shù)是在URL的問號(?)右邊部分,通常是鍵值對形式出現(xiàn)。

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

比如這個URL的查詢參數(shù)有兩個,一個是sort,一個是page,它們的值分別是ASC2。

1,指定查詢參數(shù)

查詢參數(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)了另外兩個屬性categorymodel,只要這兩個屬性其中之一發(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ù)。如下圖:

result

接著你就可以做點好玩的事了,直接在輸入框輸入分類名。由于計算屬性的特性會自動更新數(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:”
也有可能是我看不懂,反正摸索好一陣子才知道要這么用??!

2,使用link-to指定查詢參數(shù)

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)殒溄又付ǖ念愋椭担?。比如我點擊了第一個鏈接,輸入顯示如下圖:

result

3,路由轉(zhuǎn)換

route對象的transitionTo方法和controller對象的transitionToRoute方法都可以接受final類型的參數(shù)。并且這個參數(shù)是一個包括一個keyqueryParams的對象。

修改前面已經(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ù)我就不截圖了,程序不出錯,顯示的都是categoryjava的數(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');

上面的三種方式請讀者自己編寫例子試試吧。光看不練假把式……

4,選擇進入一個完整的路由

transitionTolink-to提供的參數(shù)僅會改變查詢參數(shù)的值,而不會改變路由的層次結(jié)構(gòu),這種路由的切換被認為是不完整的,這也就意味著比如modelsetupController回調(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)于這段代碼演示實例請查看官方提供的代碼!

5,使用replaceState更新URL

默認情況下,Ember使用pushState更新URL來響應controller類中查詢參數(shù)屬性的變化,但是如果你想使用replaceState來替換pushState你可以在route類中的queryParams哈希對象中設置replacetrue。設置為true表示啟用這個設置。

queryParams: {
category: {
    replaceState:true
}
}

6,將控制器的屬性映射到不同的查詢參數(shù)鍵值

默認情況下,在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

7,默認值與反序列化

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。

8,粘性的查詢參數(shù)值

默認情況下,在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,同時作用于切換前ActiclesRoutemodel。結(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ù)scopecontroller。如下:

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吧。您的肯定對我來說是最大的動力!!

以上內(nèi)容是否對您有幫助:
在線筆記
App下載
App下載

掃描二維碼

下載編程獅App

公眾號
微信公眾號

編程獅公眾號