2015-04-28 32 views
4

我遵循查詢參數指南(http://guides.emberjs.com/v1.11.0/routing/query-params/),它工作得很好。具體來說,刷新模型確實是我想要的。EmberJS:對象作爲查詢參數刷新模型

我正在將過濾器移至json-api規範,並且過濾發生在filter對象中。因此,而不是:

http://localhost:3000/accounts?id=1 

服務器響應:

http://localhost:3000/accounts?filter[id]=1 

我試圖讓查詢參數上班刷新基於對象的模型,但它似乎並沒有更新。

// app/controllers/accounts/index.js 

import Ember from 'ember'; 

export default Ember.Controller.extend({ 
    queryParams: ['filter', 'sort'], 

    filter: {}, 
    sort: '-id' 
}); 


// app/routes/accounts/index.js 
import Ember from 'ember'; 

export default Ember.Route.extend({ 
    queryParams: { 
    filter: { refreshModel: true }, 
    sort: { refreshModel: true } 
    }, 
    model: function(params) { 
    return this.store.find('account', params); 
    }, 
}); 

// template 
<th>{{input type="text" placeholder="ID" value=filter.id}}</th> 

是否有可能使查詢參數與對象一起工作?

回答

4

此答案爲Ember版本1.13.0-beta.1+canary

簡短的回答:沒有。查詢參數不適用於對象。

長的答案:

截至目前,私有函數在Router命名_serializeQueryParams序列化queryParams

_serializeQueryParams(targetRouteName, queryParams) { 
    var groupedByUrlKey = {}; 

    forEachQueryParam(this, targetRouteName, queryParams, function(key, value, qp) { 
    var urlKey = qp.urlKey; 
    if (!groupedByUrlKey[urlKey]) { 
     groupedByUrlKey[urlKey] = []; 
    } 
    groupedByUrlKey[urlKey].push({ 
     qp: qp, 
     value: value 
    }); 
    delete queryParams[key]; 
    }); 

    for (var key in groupedByUrlKey) { 
    var qps = groupedByUrlKey[key]; 
    var qp = qps[0].qp; 
    queryParams[qp.urlKey] = qp.route.serializeQueryParam(qps[0].value, qp.urlKey, qp.type); 
    } 
}, 

qp.urlKey將評估爲'filter'在你的榜樣,和對象將被序列化爲'object [Object]'。即使你可能在你的路線覆蓋serializeQueryParam方法,即不會幫助,因爲queryParam關鍵仍然是'filter',而且你需要它是'filter%5Bid%5D'

基於this comment in the Ember Discussion Forum,這聽起來像對象查詢參數是不太可能,你最好只是平整和解開濾過的區域。

1

我知道這有點晚,但是您可以使用此解決方法來允許使用查詢參數的對象。工作起來很容易,到目前爲止我還沒有發現任何問題。

我在我的JSON API(http://jsonapi.org/)上構建一個Ember應用程序時遇到了同樣的問題。

JSON API規範爲需要基於對象的查詢參數的分頁和過濾提供了推薦的語法。

對於尋呼它表明語法是這樣的:

/books?page[size]=100&page[number]=1 

和用於過濾它建議的語法如下:

/books?filter[author]=Bob 

雖然Ember.js查詢參數(如灰燼V2.1的)做不支持這種開箱即用的方式,它的工作起來相當簡單。在您的控制器中,您應該將控制器屬性映射爲查詢參數「object」作爲字符串。

例如,在上面的「過濾器」示例中,您可以將名爲filterByAuthorValue的控制器屬性映射到查詢參數filter[author]

要做到這一點應該是這樣的代碼:

export default Ember.Controller.extend({ 
    queryParams: ['sort',{ 
    filterByAuthorValue: 'filter[author]' 
    }], 
    sort: '', 
    filterByAuthorValue: '' 
}); 

注意,在上面的例子中我也有一個查詢參數排序稱爲(也遵循JSON API建議,但並不需要的對象)。有關控制器屬性映射到查詢參數的詳細信息請參考官方Ember.js指南的這一部分:

http://guides.emberjs.com/v2.1.0/routing/query-params/#toc_map-a-controller-s-property-to-a-different-query-param-key

一旦你的查詢參數創建的,那麼你需要處理查詢在你的路由器中的參數。

export default Ember.Route.extend({ 
    queryParams: { 
    sort: { 
     refreshModel: true 
    }, 
    filterByAuthor:{ 
     refreshModel: true 
    } 
    } 
}); 

最後,你現在需要的,當你加載路由器的model方法模型到控制器財產filterByAuthor轉化爲實際的對象:首先,當控制器屬性filterByAuthor變化,路由器應該強制模型被刷新並從控制器屬性filterByAuthor中分配值。然後,全路由器代碼是這樣:

export default Ember.Route.extend({ 
    queryParams: { 
    sort: { 
     refreshModel: true 
    }, 
    filterByAuthor:{ 
     refreshModel: true 
    } 
    }, 
    model: function(params){ 
    // The params value for filtering the entity name 
    if(params.filterByAuthor){ 
     params.filter = {}; 
     params.filter['author'] = params.filterByAuthor; 
     delete params.filterByAuthor; 
    } 
    return this.store.query('book', params); 
    }, 
}); 

設置的東西像這使得基於對象查詢參數與灰燼使用,因此遵循JSON API建議。

上面已經過測試與下列版本:

Ember    : 2.1.0 
Ember Data  : 2.1.0 
jQuery   : 1.11.3