将项目添加到来自 ember-data 的过滤结果 [英] Adding item to filtered result from ember-data

查看:14
本文介绍了将项目添加到来自 ember-data 的过滤结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 DS.Store,它使用了 DS.RESTAdapter 和一个 ChatMessage 对象,定义如下:

I have a DS.Store which uses the DS.RESTAdapter and a ChatMessage object defined as such:

App.ChatMessage = DS.Model.extend({
    contents: DS.attr('string'),
    roomId:   DS.attr('string')
});

请注意,房间中存在聊天消息(为简单起见未显示),因此在我的聊天消息控制器(扩展 Ember.ArrayController)中,我只想为用户加载房间的消息目前在:

Note that a chat message exists in a room (not shown for simplicity), so in my chat messages controller (which extends Ember.ArrayController) I only want to load messages for the room the user is currently in:

loadMessages: function(){ 
    var room_id = App.getPath("current_room.id");
    this.set("content", App.store.find(App.ChatMessage, {room_id: room_id}); 
}

这将 content 设置为 DS.AdapterPopulatedModelArray 并且我的视图愉快地以 {{#each}} 显示所有返回的聊天消息> 阻止.

This sets the content to a DS.AdapterPopulatedModelArray and my view happily displays all the returned chat messages in an {{#each}} block.

现在要添加一条新消息,我在同一个控制器中有以下内容:

Now it comes to adding a new message, I have the following in the same controller:

postMessage: function(contents) {
    var room_id = App.getPath("current_room.id");
    App.store.createRecord(App.ChatMessage, {
        contents: contents,
        room_id: room_id
    });

    App.store.commit();
}

这会发起一个ajax请求将消息保存在服务器上,到目前为止一切都很好,但它并没有更新视图.这几乎是有道理的,因为它是一个过滤结果,如果我删除 App.store.find 上的 room_id 过滤器,那么它会按预期更新.

This initiates an ajax request to save the message on the server, all good so far, but it doesn't update the view. This pretty much makes sense as it's a filtered result and if I remove the room_id filter on App.store.find then it updates as expected.

使用 App.store.createRecord 返回的消息记录尝试 this.pushObject(message) 会引发错误.

Trying this.pushObject(message) with the message record returned from App.store.createRecord raises an error.

如何手动将项目添加到结果中?据我所知,似乎没有办法,因为 DS.AdapterPopulatedModelArrayDS.FilteredModelArray 都是不可变的.

How do I manually add the item to the results? There doesn't seem to be a way as far as I can tell as both DS.AdapterPopulatedModelArray and DS.FilteredModelArray are immutable.

推荐答案

几个想法:

(参考:https://github.com/emberjs/data/issues/190)

如何侦听数据存储区中的新记录

一个普通的 Model.find()/findQuery() 将返回一个 AdapterPopulatedModelArray,但该数组将独立存在......它不会知道任何新的东西已被加载到数据库中

a normal Model.find()/findQuery() will return you an AdapterPopulatedModelArray, but that array will stand on its own... it wont know that anything new has been loaded into the database

没有参数的 Model.find()(或 store.findAll())将返回一个 FilteredModelArray 的所有记录,并且 ember-data 会将它注册"到一个列表中,任何加载到数据库中的新记录都会被添加到这个数组中.

a Model.find() with no params (or store.findAll()) will return you ALL records a FilteredModelArray, and ember-data will "register" it into a list, and any new records loaded into the database will be added to this array.

调用 Model.filter(func) 会给你一个 FilteredModelArray,它也在商店注册......商店中的任何新记录都会导致 ember-data 为updateModelArrays",这意味着它会调用你的过滤器使用新记录执行函数,如果您返回 true,那么它会将其粘贴到您现有的数组中.

calling Model.filter(func) will give you back a FilteredModelArray, which is also registered with the store... and any new records in the store will cause ember-data to "updateModelArrays", meaning it will call your filter function with the new record, and if you return true, then it will stick it into your existing array.

我最终做了什么:在创建商店之后,我立即调用了 store.findAll(),它返回了一个类型的所有模型的数组……然后我将它附加到商店……然后在代码中的任何其他地方,我可以将ArrayObservers 添加到这些列表中.. 类似于:

SO WHAT I ENDED UP DOING: was immediately after creating the store, I call store.findAll(), which gives me back an array of all models for a type... and I attach that to the store... then anywhere else in the code, I can addArrayObservers to those lists.. something like:

App.MyModel = DS.Model.extend()
App.store = DS.Store.create()
App.store.allMyModels = App.store.findAll(App.MyModel)

//some other place in the app... a list controller perhaps
App.store.allMyModels.addArrayObserver({
   arrayWillChange: function(arr, start, removeCount, addCount) {}
   arrayDidChange: function(arr, start, removeCount, addCount) {}
})

如何将模型推入这些不可变"数组之一:

首先要注意:所有 Ember-Data 模型实例(记录)都有一个 clientId 属性......这是一个唯一的整数,用于标识数据存储缓存中的模型是否具有真实server-id(例如:在执行 Model.createRecord 之后).

First to note: all Ember-Data Model instances (records) have a clientId property... which is a unique integer that identifies the model in the datastore cache whether or not it has a real server-id yet (example: right after doing a Model.createRecord).

所以 AdapterPopulatedModelArray 本身有一个内容"属性......它是这些 clientId 的数组......当你遍历 AdapterPopulatedModelArray 时,迭代器循环遍历这些 clientId 并将完整的模型实例(记录) 映射到每个 clientId.

so the AdapterPopulatedModelArray itself has a "content" property... which is an array of these clientId's... and when you iterate over the AdapterPopulatedModelArray, the iterator loops over these clientId's and hands you back the full model instances (records) that map to each clientId.

我做了什么(这并不意味着它是正确的"!)是观察那些 findAll 数组,并将新的 clientId 推送到 AdapterPopulatedModelArray 的 content 属性中......类似的东西:

SO WHAT I HAVE DONE (this doesn't mean it's "right"!) is to watch those findAll arrays, and push new clientId's into the content property of the AdapterPopulatedModelArray... SOMETHING LIKE:

arrayDidChange:function(arr, start, removeCount, addCount){
    if (addCount == 0) {return;} //only care about adds right now... not removes...
        arr.slice(start, start+addCount).forEach(function(item) {
            //push clientId of this item into AdapterPopulatedModelArray content list
            self.getPath('list.content').pushObject(item.get('clientId'));
        });
    }

我能说的是:它对我有用":) 它会在下一次 ember-data 更新时中断吗?完全有可能

what I can say is: "its working for me" :) will it break on the next ember-data update? totally possible

这篇关于将项目添加到来自 ember-data 的过滤结果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆