【问题标题】:EmberJS: how to remove records with many-to-many relationshipEmberJS:如何删除具有多对多关系的记录
【发布时间】:2015-01-22 14:13:58
【问题描述】:

当我尝试删除其模型与另一个模型具有多对多关系的记录时,我偶然发现了一个问题。

我有书:

App.Book = DS.Model.extend({
    title: DS.attr('string'),
    isbn: DS.attr('string'),
    category: DS.attr('string'),
    publishDate: DS.attr('date'),
    authors: DS.hasMany('author', {inverse: 'books'})
});

以及作者:

App.Author = DS.Model.extend({
    firstName: DS.attr('string'),
    lastName: DS.attr('string'),
    birthDate: DS.attr('date'),
    books: DS.hasMany('book', {async: true, inverse: 'authors'})
});

我正在删除这样的书:

actions: {
    delete: function (book) {
        var authors = book.get('authors')
        authors.forEach(function(author) {
            var books = author.get('books')
            books.forEach(function(book){
                console.log(book.toJSON());
            })
            books.removeObject(book);
            //books.save doesn't work
        })
        book.destroyRecord();
        this.transitionToRoute('books.index');
    },

它正确地删除了这本书,并向支持 REST 服务器发出了 DELETE 请求,但是对于所有在他们的“书籍”集合中拥有这本书的作者没有 PUT 请求。当我将视图更改为作者并返回书籍时,会创建一本带有我之前删除的书籍的 id 的虚拟书籍,并且“作者”也设置为旧作者,其他属性未定义。

如何正确删除图书以便作者也得到更新?

【问题讨论】:

  • 您使用 Ember Data Beta 14 吗?当您看到“虚拟”书时,您是否在控制台中收到任何错误?

标签: ember.js many-to-many ember-data


【解决方案1】:

你必须记住DS.hasMany返回一个promise,所以在你使用它之前必须先解决它:

  actions: {
    delete: function (book) {
     if (!book.get('isDeleted')) {
       book.destroyRecord()
         .catch(function(error) {
           console.log(error);
           book.rollback();
         })
         .then(function(book) {
           book.get('authors').then(function (authors) {
             authors.mapBy('books').forEach(function(books) {
                if (typeof books.then === "function") {
                  books.then(function(books) {
                    books.removeObject(book);
                  });
                } else {
                  books.removeObject(book);
                }
             });
           });
         });
      }

      this.transitionToRoute('books.index');
    }
  },

【讨论】:

  • 在尝试您的解决方案时,我得到了这个:TypeError: undefined is not a function at controllers.js:25 其中 25 是 `book.get('authors').then(function (authors) {` delete 操作被放置在 BookController 中我正在传递一本书作为参数(感觉不对,删除我当前所在控制器中的书不是更好吗?但是在删除参数并将书声明为this.get('model')之后它仍然没有't work),这就是为什么它不是一个承诺。
【解决方案2】:

看来我已经解决了。 第一个问题是,在我的项目的服务器端,我错误地填充了数据 - id 错误并且与它们的关系中的那些不匹配。

另一件事是保存不正确的对象。我试图只保存带有书籍的数组,而不得不保存整个作者(实际上这是有道理的)。工作动作是这样的:

console.log('Removing book: ' + book.get('id') + book.get('title'));
var authors = book.get('authors')
var id = book.get('id');
authors.forEach(function (author) {
   var books = author.get('books').removeObject(book);
   author.save();
})
book.destroyRecord();
this.transitionToRoute('books.index');

我唯一的疑问是删除操作是在 BookController 中定义的,它的模型是我要删除的书,所以我不应该将书放在参数中,而是使用控制器的模型。而且我刚刚发现只需删除参数并将 book 声明为this.get('model') 即可轻松实现,这就是为什么最终的可行解决方案是这样的:

delete: function () {
    var book = this.get('model')
    console.log('Removing book: ' + book.get('id') + book.get('title'));
    var authors = book.get('authors')
    var id = book.get('id');
    authors.forEach(function (author) {
        var books = author.get('books').removeObject(book);
        author.save();
    })
    book.destroyRecord();
    this.transitionToRoute('books.index');
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-28
    • 1970-01-01
    • 2014-01-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-16
    • 1970-01-01
    相关资源
    最近更新 更多