简体   繁体   English

灰烬数据交易错误

[英]Ember-Data transaction error

I'm having an issue with Ember-Data transactions. 我在Ember-Data交易中遇到问题。

I have a DS.Model like so 我有一个像这样的DS.Model

App.MyModel = DS.Model.extend({
    id: DS.attr(),
    answers: DS.hasMany('App.Answer') // another model 
});

Then it is initiated later like so, in the a Route 然后像这样在路由中稍后启动

model: function(){
     var transaction = this.get('store').transaction();

     return transaction.createRecord(App.MyModel, {
         id: '1'
     });
}

I have a Model that makes a request to my back end server using transaction and commit. 我有一个使用事务和提交向后端服务器发出请求的模型。

this.get('content.transaction').commit();

With the intent that answers is updated on the server side and sent back to me. 目的是在服务器端更新答案并将其发送给我。 If the content hasn't been updated yet, I call this 如果内容尚未更新,我称之为

this.get('content').reload();

And the request is sent again. 并再次发送请求。

This all works fine. 这一切都很好。 answers gets populated if the id is found. 如果找到ID,则会填充答案。

My issue is that occasionally, depending on what I get back from the server, I have to make another server request. 我的问题是,有时候,根据我从服务器获得的信息,我必须提出另一个服务器请求。 The initial request works fine with 初始请求可以与

this.get('content.transaction').commit();

but when I try to reload the transaction, I get an error, as follows 但是当我尝试重新加载事务时,出现如下错误

Uncaught Error: Attempted to handle event `loadedData` on <App.Answer> while in state rootState.loaded.updated.uncommitted. Called with undefined

Now when I remove the reload, I no longer get the error, also when I check the console of Chrome under the network tab, I can see that the results I want are being sent back but they are not being updated in my DS Model. 现在,当我删除重新加载时,不再出现错误,而且当我在“网络”选项卡下检查Chrome的控制台时,我可以看到我想要的结果已发回,但在我的DS模型中没有更新。 answers is left undefined. 答案是不确定的。

Anyone know why this is happening? 有人知道为什么会这样吗? Am I using the transactions wrong? 我使用交易有误吗?

EDIT 编辑

Application.SearchController = Ember.ObjectController.extend({
    isComplete: function () {
        return this.get('content.answers.length') !== 0;
    },


    search: function () {
        this.get('content.transaction').commit();

        var record = this.get('content');

        var interval = setInterval(function (controller) {
            if (controller.get('isComplete')) {
                controller.transitionToRoute("search.view");
                clearInterval(interval);
            } else {
                record.reload();
            }
        }, 5000, this);
    }
 });

SO basically some work in done in my route to set up my models and set them to the content, the model has an id that will be used on the server side and sent back with the results of the search then added to "answers". 因此,基本上,我在完成设置模型并将其设置为内容的过程中做了一些工作,该模型具有一个ID,该ID将在服务器端使用,并随搜索结果一起发送回去,然后添加到“答案”中。

This work fine until there are multiple results are found. 正常工作,直到找到多个结果。 Then a new model is created and the search function is called again on a different controller, with different content. 然后创建一个新模型,并在具有不同内容的其他控制器上再次调用搜索功能。 This time round on the line record.reload(); 这次是在记录行。

I get the error Uncaught Error: Attempted to handle event loadedData on while in state rootState.loaded.updated.uncommitted. 我得到的错误未被捕获的错误:试图处理事件loadedData上,而在状态rootState.loaded.updated.uncommitted。 Called with undefined 用未定义调用

So the server still responds with the correct results but the "answers" is not updated on the client side. 因此,服务器仍然以正确的结果进行响应,但是客户端不会更新“答案”。

Your MyModel record is locally modified (client side). 您的MyModel记录是本地修改的(客户端)。 Calling reload will try to update it, which is prohibited in the current state of the record. 调用reload会尝试更新它,这在记录的当前状态中是禁止的。

You can check this with a command: 您可以使用以下命令进行检查:

console.log( this.get('content.stateManager.currentState.path') );
this.get('content').reload();

This should display in your console that the record is in the uncommitted state. 这将在您的控制台中显示该记录处于uncommitted状态。

UPDATE: 更新:

You can't use a timer. 您不能使用计时器。 Everything is asynchronous and you have no guarantee that your model will be updated during that interval. 一切都是异步的,您不能保证在此间隔内将更新模型。 Which means that while you commit your record, you may reload it at the same time (this would generate the error you see). 这意味着在提交记录时,您可以同时重新加载它(这会产生您看到的错误)。

What you want is something like that: 您想要的是这样的:

Application.SearchController = Ember.ObjectController.extend({
    search: function () {
        var record = this.get('content'),
            controller = this;

        record.one('didCommit', function() {
            controller.transitionToRoute("search.view"); 
        });

        record.transaction.commit();
    }
});

After the first commit the transaction is placed on the default transaction. 第一次提交后,该事务将放在默认事务上。

Error Attempted to handle event `loadedData` : Object not updated after deleteRecord 尝试处理事件`loadedData`时出错:deleteRecord之后对象未更新

And remember always setup the router first. 并记住始终先设置路由器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM