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

Updating a resource model after saving a new model instance and before transitioning to route in Ember.js

本文关键字:模型 资源 更新 路由 转换 Ember 保存 实例 js 之后      更新时间:2023-09-26

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

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

视图中只列出了MongoDB集合中的前10只鞋,正如我们的webbneneneba API中所指定的那样。创建新鞋(使用嵌套路线"new")并转换回"/shoes"时,新鞋将添加到当前的"shoes"模型中。

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

这就产生了一个包含11双鞋的列表。换句话说,它不使用路由并进行新的API调用。相反,它会添加到模型中的当前鞋子列表中。刷新页面时,结果将按预期呈现,获取DB集合的10条第一记录。

我们希望让"transitionToRoute"执行路由并重新获取模型,而不仅仅是将其添加到当前模型中。我们已经看到了一些关于"this.refresh()"answers"this.reload())"如何在控制器的"模型"作用域主体中使用的例子,但这些例子对我们不起作用。

是否可以使用"shoes"路由使用新的数据库值进行"transitionToRoute"刷新模型?

根据您所写的内容,我猜您正试图使用分页,并且只想在/shoes路线上列出前10双鞋?

如果是这样的话,"Ember方式"就是始终保持所有模型的同步,而不必为了人工更新视图而做特殊的工作。在这种情况下,Ember有一个shoes的本地商店,它最初有10个项目。然后你再添加一双,它会被保存在数据库和Ember本地商店中,所以现在Ember认为(正确的)你有11双鞋。Mongo返回10只鞋并不意味着你的整个数据集就是10只鞋。

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

在实践中,我在ArrayController上看到了两种类型的过滤。一种是只返回第一个n值。为此,请使用好的旧javascript slice(请参阅MDN文档)。二是使用Ember filter函数。参见Ember文档。

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

鞋控制器:

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