在保存新模型实例之后以及在Ember.js中转换到路由之前更新资源模型

时间:2014-09-26 16:13:33

标签: javascript mongodb ember.js routes

使用Ember,我们有一个从数据库中提取的鞋子列表。这些列在'/ shoes。

this.resource('shoes', function() {
  this.route('new');
  this.route('show', {path: ':shoe_id'});
  this.route('edit', {path: ':shoe_id/edit'});
});

在我们的webb API中指定的视图中仅列出了MongoDB集合中的前10个鞋子。在创建新鞋时(使用嵌套路线'new'),并转换回'/ shoes',新鞋将添加到当前的'鞋'模型中。

export default Ember.ObjectController.extend({
  actions: {
    save: function() {
      this.get('model').save();
      this.transitionToRoute('shoes');
    }
  }
});

这导致了11个鞋子的清单。换句话说,它不使用该路由并进行新的API调用。相反,它会添加到模型中当前的鞋子列表中。刷新页面时,结果将按预期呈现,从而获取数据库集合的10个第一条记录。

我们希望让'transitionToRoute'执行路由并重新获取模型,而不是仅仅将其添加到当前模型中。我们已经看到了一些如何在控制器的“模型”范围体内使用'this.refresh()'和'this.reload()'的例子,但这些例子对我们没有用。

是否可以使用'shoes'路线使'transitionToRoute'使用新的数据库值刷新模型?

1 个答案:

答案 0 :(得分:1)

根据您所写的内容,我猜测您是否尝试使用分页,并且只希望在您的/shoes路线上列出前10个鞋子?

如果是这样的话," Ember Way"是为了始终保持所有模型的同步,并且永远不必为了让视图人工更新而做必要的工作。在这种情况下,Ember有一个shoes的本地商店,最初有10个商品。然后再添加一个,它将保存到数据库和Ember本地商店,所以现在Ember认为(正确地)你有11个鞋子。仅仅因为Mongo返回10件鞋并不意味着你的整个数据集都是10鞋。

因此,处理这种情况的最佳方法是让您的视图显示基础模型数据的准确投影。换句话说,不要告诉你的观点显示所有的鞋子"。告诉它显示所有鞋子的过滤清单"!

在实践中,我在ArrayController上看到了两种类型的过滤。一种是返回第一个n值。为此使用好的旧javascript sliceSee MDN docs)。第二种是使用Ember filter函数。 See Ember Docs

最终,你的控制器会是这样的:

鞋子控制器:

export default Ember.ArrayController.extend( PaginatorClientSideMixin, {

    shoesFilteredOption1: function() {
        return this.get('arrangedContent') // 'arrangedContent' is the sorted list of underlying content; assumes your backing model is the DS.RecordArray of shoes
            // this use of slice takes an array and returns the first 10 elements
            .slice( 0, 10 );

        // we depend on 'arrangedContent' because everytime this changes, we need to recompute this value
    }.property('arrangedContent')

    shoesFilteredOption2: function() {
        return this.get('arrangedContent') // 'arrangedContent' is the sorted list of underlying content; assumes your backing model is the DS.RecordArray of shoes
            // here we're filtering the array to only return "active" shoes
            .filter( function(item, index, self ) {
                if (item.isActive) { return true; }
            })
    }.property('arrangedContent')

});

然后在您的Handlebars模板上阅读shoesFilteredOption1而不是contentmodel