简体   繁体   English

如何使用Ember-data更新Ember.js中的仅1条记录? 当前在1条记录上的save()和commit()实际上更新了模型的所有记录

[英]How to update just 1 record in Ember.js with Ember-data? Currently save() and commit() on 1 record actually updates all records of model

Premise: My question is based on my research of Ember-data, which may or may not be correct. 前提:我的问题是基于对Ember数据的研究得出的,该结论可能正确也可能不正确。 So please correct me if I have any misunderstanding. 因此,如果我有任何误解,请纠正我。 The examples are running with the latest ember as of July 2, 2013. 截至2013年7月2日,示例使用最新的余烬运行。

To edit a record of my model, just 1 record, you need to call this.get('store').commit() or this.get('model').save() . 要编辑我的模型的记录(仅1条记录),您需要调用 this.get('store').commit()this.get('model').save() However, downstream of either of these functions actually have to update all of the records of the model, even those left untouched. 但是,这些功能中的任何一个的下游实际上都必须更新模型的 所有记录,即使是未修改的记录也是如此。 So this is quite inefficient, especially if the model has numerous records. 因此,这效率很低,尤其是在模型具有大量记录的情况下。

What's the best way to update one and only one record when I'm saving the edits of one record? 当我保存一条记录的编辑内容时,更新一条和一条记录的最佳方法是什么?

UPDATE: this problem only occurs for the local-storage-adapter , not the RESTAdapter . 更新:此问题仅在 local-storage-adapter而不是 RESTAdapter上发生

UPDATE #2: I did have a huge misunderstanding. 更新#2:我确实有很大的误解。 Everything is okay, save() and commit() both update just 1 record, I've been fooled by local storage adapter _saveData 's JSON.stringify(this._data) which printed out all records. 一切正常,save()和commit() _saveData更新1条记录,我被本地存储适配器_saveDataJSON.stringify(this._data)愚弄了,该输出了所有记录。 I assumed that whatever it printed out was the data that is changed, but turns out in _saveData 's callers the records in updateRecords and _didSaveRecords were just the single record I was changing. 我以为,不管它打印出来是改变的数据,但在原来_saveData的来电者的recordsupdateRecords_didSaveRecords只是我改变了单个记录。 The statements below about different objects containing "all records of the model" can no longer be duplicated. 下面关于包含“模型的所有记录”的不同对象的陈述将不再重复。 I guess I misread the debugging information. 我想我误读了调试信息。
It makes sense because _saveData uses localstorage, which currently can only setItem for an entire object , which in my case is the model containing all the records. 这是有道理的,因为_saveData使用localstorage,当前只能为整个对象设置setItem ,在我的情况下,该模型是包含所有记录的模型。 Since localstorage can't update individual entries of that object, the JSON must contain all the records. 由于localstorage无法更新该对象的单个条目,因此JSON必须包含所有记录。


Details: 细节:

Running Examples: 运行示例:

If you turn on Chrome debug and walk into the above two functions, you'll see something similar to below: 如果您打开Chrome调试并进入以上两个功能,则会看到类似以下内容:

  1. Downstream, there is currentTransaction or defaultTransaction , and both have all records of the model inside . 下游有 currentTransactiondefaultTransaction ,并且 都在内部具有模型的所有记录

    In the case of get('store').commit(), it eventually calls DS.Store's commit , which in turn calls: (see github ) 对于get('store')。commit(),它最终会调用DS.Store的 commit ,而 commit依次调用:(请参阅 github

     
       
       
       
        
        
        get(this, 'defaultTransaction').commit();
       
       
        

    In the case of case of get('model').save(), it eventualy calls DS.Store's scheduleSave and flushSavedRecords , which call: (see github ) 在get('model')。save()的情况下,它最终会调用DS.Store的 scheduleSaveflushSavedRecords ,它们调用:(请参阅 github

     
       
       
       
        
        
        get(this, 'currentTransaction').add(record); get(this, 'currentTransaction').commit();
       
       
        

    Note at the end a commit() is called on xxxTransaction, this is DS.Transaction's commit() . 请注意,最后在xxxTransaction上调用了 commit() ,这是DS.Transaction的 commit()

  2. DS.Transaction s commit() has a commitDetails , which is based on xxxTransaction, so commitDetails` also has all the records of the data. DS.Transaction s commit() has a , which is based on xxxTransaction, so commitDetails也具有数据的所有记录。 ( github ) github

  3. Then DS.Adapter's commit and save are called and indeed every single record is updated ( github ): 然后调用DS.Adapter的 commitsave ,实际上每条记录都会更新( github ):

     
       
       
       
        
        
        this.groupByType(commitDetails.updated).forEach(function(type, set) { this.updateRecords(store, type, filter(set)); }, this);
       
       
        

    (minor side note/question: when was commitDetails set to "updated"?) (次要注意事项/问题:何时将commitDetails设置为“ updated”?)

I know that DS.Adapter can be customized, but clearly the problem of saving more than one data (ie all of the model entries) are set from DS.Store's commitDefaultTransaction and currentTransaction . 我知道DS.Adapter可以自定义,但是显然可以通过DS.Store的 commitDefaultTransactioncurrentTransaction设置保存多个数据(即所有模型条目)的 commitDefaultTransaction

Somehow I feel it would be a bad idea to tinker with DS.Store or anything upstream of DS.Adapter, like making my own version of save() and commit(). 我觉得以某种方式修改DS.Store或DS.Adapter上游的任何内容都是一个坏主意,例如制作自己的save()和commit()版本。 Basically I am reluctant to customize anything I'm told not to, since there might be ugly side effects. 基本上,我不愿意自定义任何不被告知的内容,因为可能会有丑陋的副作用。

So what should I do if I want to use Ember data but can only afford to update one record only at a time? 因此,如果我想使用Ember数据但一次只能更新一条记录,该怎么办?

You can create a new transaction just for managing that record, using transaction() method of the store . 您可以使用store transaction()方法创建一个仅用于管理该记录的新事务。 This transaction has the same api as the defaultTransaction . 此事务具有与defaultTransaction相同的api。

var transaction = this.get('store').transaction();
transaction.add(model)
transaction.commit();

Committing this transaction won't affect other changes. 提交此交易不会影响其他更改。 See this blog post for further ideas. 请参阅此博客文章以获取更多想法。

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

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