EmberJS:对象作为刷新模型的查询参数

时间:2015-04-28 20:42:07

标签: javascript ember.js

我按照查询参数指南(http://guides.emberjs.com/v1.11.0/routing/query-params/)进行操作,效果很好。具体来说,刷新模型完全符合我的要求。

我将过滤器移动到json-api规范,过滤在friends/2对象中进行。所以而不是:

filter

服务器响应:

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

我试图让查询参数基于对象刷新模型,但它似乎没有更新。

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

是否可以让查询参数与对象一起使用?

2 个答案:

答案 0 :(得分:4)

此答案与Ember版本private void ListView_MouseDoubleClick(object sender, MouseButtonEventArgs e) { DependencyObject clickedObj = (DependencyObject)e.OriginalSource; while (clickedObj != null && clickedObj != listDiscussion) { if (clickedObj.GetType() == typeof(ListViewItem)) { Discussion selectedDiscussion = (Discussion)listDiscussion.ItemContainerGenerator .ItemFromContainer((ListViewItem)listDiscussion.SelectedItem); this.NavigationService.Navigate(new MessagePage(selectedDiscussion)); break; } clickedObj = VisualTreeHelper.GetParent(clickedObj); } } 相同。

简答:否。查询参数不适用于对象。

答案很长:

截至目前,1.13.0-beta.1+canary中名为_serializeQueryParams的私有函数序列化了Router

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'

基于this comment in the Ember Discussion Forum,听起来像对象查询参数不太可能,而且只需将滤平字段展平并取消平整,您就会感觉更好。

答案 1 :(得分:1)

我知道这有点晚了但你可以使用这种解决方法来允许带有查询参数的对象。它很容易上班,到目前为止我还没有发现任何问题。

在我的JSON API(http://jsonapi.org/)上构建Ember应用程序时遇到了同样的问题。

JSON API规范为分页和过滤提供了推荐的语法,需要基于对象的查询参数。

对于分页,建议语法如下:

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

并且为了过滤它建议语法如下:

/books?filter[author]=Bob

虽然Ember.js查询参数(从Ember v2.1开始)不支持开箱即用,但开始工作相当简单。在您的控制器中,您应该将控制器属性映射到查询参数" object"作为一个字符串。

例如,在上面的"过滤器"例如,您将名为filterByAuthorValue的控制器属性映射到查询参数filter[author]

执行此操作的代码如下所示:

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

请注意,在上面的示例中,我还有一个名为sort的查询参数(它也遵循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

创建查询参数后,您需要处理路由器中的查询参数。首先,当控制器属性filterByAuthor发生更改时,路由器应强制刷新模型:

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

最后,当您在路由器的filterByAuthor方法中加载模型并从控制器属性{{1}中分配值时,您现在需要将控制器属性model转换为实际对象。 1}}。完整的路由器代码如下所示:

filterByAuthor

这样的设置允许基于对象的查询参数与Ember一起使用,从而遵循JSON API建议。

以上版本已通过以下版本测试:

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);
  },
});