Ember数据:Sideloaded记录在Store和奇怪的行为中创建重复项

时间:2014-01-30 01:05:13

标签: javascript ember.js ember-data

我们的服务器返回与请求不完全相关的额外侧载记录,这应该有效,但它会导致存储中的重复记录和奇怪的UI行为。 (http://jsfiddle.net/jgillick/agYMQ/

为了简化它,想象两个模型:儿童和玩具。孩子有很多玩具。当您向孩子添加玩具时,XHR不仅会响应新玩具记录,还会对子对象和玩具列表进行侧载。这样,更多的UI可以使用一个请求进行更新。 JSON最终看起来像这样:

{
    "toy": {
        "id": 1,
        "name": "doll",
        "quantity": 1
    },
    "children": [
        {
            "id": 0,
            "name": "Ben",
            "quantity": 1,
            "toys": [0, 1]
        }
    ],
    "toys": [
        {
            "id": 0,
            "name": "car",
            "quantity": 1
        },
        {
            "id": 1,
            "name": "doll",
            "quantity": 1
        }
    ]
}

由于某种原因,这会导致余烬商店的记录阵列中有3个玩具。这不应该发生,因为这些项目具有ID。因此,加载具有重复ID的记录会导致它覆盖前一个ID。相反,当我查看商店的记录数组时,记录是重复的 - ID和所有。

另一个奇怪的效果是当您添加第一个玩具时,会在模板中为其创建列表项,但所有值都是未定义的。添加第二个玩具后,UI会按预期更新。试试jsfiddle:http://jsfiddle.net/jgillick/agYMQ/

是否真的不可能像这样加载额外的记录?有解决方案还是我只是忽略了什么?

1 个答案:

答案 0 :(得分:0)

这是一个有趣的困境,如果在同一个回复中多次返回相同的记录,我不确定Ember是否应该知道谁是获胜者的记录(我个人会选择第二个记录,但我不知道) 。无论这种边缘情况是不受支持的(不是它不应该,但可能是较低的优先级)。

关于你看到的另一个问题,我认为通过手动设置内容会遇到某种代理问题,我对此并不乐观,但无论如何这里都是Ember的设置方式。

http://jsfiddle.net/QVqun/

App.IndexRoute = Em.Route.extend({
    model: function(){
        return this.store.createRecord("child", {
                'name': childName
            });
    }
});

//
// Main Program
//
App.IndexController = Em.ObjectController.extend({

    actions: {

        // Add a toy to the child
        addToy: function(){
            var self = this,
                store = this.get('store'),
                toys = this.get('model.toys'),
                toy = nextToy();

            // Create toy and add it to the child
            toy = store.createRecord('toy', {
                'name': toy.name,
                'quantity': toy.quantity
            });

            toys.pushObject(toy);
            // Save the new toy
            toy.save();
        }
    },

    storeToys: function(){
        return this.store.all('toy');
    }.property(),

    storeToysLen: Em.computed.alias('storeToys.length')

});