2014-06-09 90 views
5

在我正在构建的Ember应用程序中,我有一个ArrayController,它用一个排序按钮管理包含数组中每个记录对象的几列数据的项目列表在视图中的每个列标题中。根据Balint Erdi推荐的方法here,我已经建立了列表来对给定的列进行排序。您将在下面的代码中看到此排序。Ember.js:从排序的ArrayController中删除一个项目

排序工作正常。然而,当我从数组中删除一个项目时出现问题。目前,当我尝试从数组中删除一个项目时,正确的项目显然是从数组中删除,并从商店中正确删除,删除保存到我的后端。但是,删除项目后,我的观点不正确。在某些情况下,错误的项目会显示为已移除,但在其他情况下,没有项目会显示为已移除。然而,如果我再次按排序,视图会正确更新。

所以,数组的索引显然是一些如何,但我不知道如何和所有的尝试应用别人的技巧是行不通的!

这里是我的路由对象:

App.UsersFilesRoute = Ember.Route.extend({ 
    model: function() { 
     return this.modelFor('users').get('files'); 
     } 
    }); 

这里是我的ArrayController:

App.UsersFilesController = Ember.ArrayController.extend({ 
    sortProperties: ['name'], 
    sortedFiles: Ember.computed.sort('model', 'sortProperties'), 
    actions: { 
     addFile: function(file) { 
     var newFile = this.store.createRecord('file', { 
      name: file.name.trim(), 
      fileSize: file.size, 
      loaded: false 
     }); 
     this.pushObject(newFile); 
     }, 
     sortBy: function (sortProperties) { 
     this.set('sortProperties', [sortProperties]); 
     }, 
     removeFile: function (fileToRemove) { 
     var _this = this; 
     var file = this.store.find('file', fileToRemove.get('id')); 
     file.then(function (file) { 
      _this.removeObject(file); 
      file.deleteRecord(); 
      file.save(); 
     }); 
     }, 
     saveFile: function (file) { 
     .... 
     } 
    } 
    }); 

这里是我的模板代码:

<div class="hidden-xs row user-file-header-row"> 
    <div class="col-sm-5 col-md-5 user-file-header"> 
     File Name 
     <button type="button" class="btn-xs btn-default files-sort-btn" {{ action 'sortBy' 'name'}}></button> 
    </div> 
    <div class="col-sm-1 col-md-1 user-file-header"> 
     Size 
     <button type="button" class="btn-xs btn-default files-sort-btn" {{ action 'sortBy' 'fileSize'}}></button> 
    </div> 
    </div> 
    {{#each file in sortedFiles}} 
    <div class="row user-file user-file-break"> 
     <div class="col-xs-11 col-sm-5 col-md-5 user-file-name"> 
     <a {{ bind-attr href="file.path" }} >{{ file.name }} </a> 
     </div> 
     <div class="col-xs-9 col-sm-1 col-md-1"> 
     {{ format-file-size file.fileSize }} 
     </div> 
     <div class="col-xs-9 col-sm-1 col-md-1"> 
     <button type="button" class="btn-xs btn-default files-list-btn" {{ action 'removeFile' file }}></button> 
     </div> 
    </div> 
    {{/each}} 

注:之间有一定的相似性我的问题和这个其他StackOverflow问题:After using jQuery UI to sort an Ember.js item, using Ember Data's model.deleteRecord() doesn't work,但是,我试图t o适用于回答我自己的问题而没有成功。此外,我没有jQuery在我的排序。

+0

你会显示格式文件大小,一般来说你会遇到haywire与坏html相关的问题,虽然你的上面看起来不错。我的例子没有显示类似的问题:http://emberjs.jsbin.com/xokemala/1/edit – Kingpin2k

回答

2

好的。我找到了答案,或者更确切地说,答案找到了我。

我的问题是,在上面的代码中,我从ArrayController中删除项目,然后调用.delete()和.save()。这些调用序列向Ember发送冲突信号,以便更新我的视图。显然,.removeObject()实际上是从数组中删除项目,但随后的.delete()/。save()将视图后面的模型设置为删除之前的状态(不确定,但那就是我看到了发生)。

因此,无论如何,.destroyRecord()会返回一个承诺,所以我将.rehen()中的.removeObject()移动到承诺中,并解决了问题。

所以,在removeFile动作下面的代码解决了这个问题:

removeFile: function() { 
    var self = this; 
    var fileToRemove = this.get('fileToRemove'); 
    var file = this.store.find('file', fileToRemove.get('id')); 
    file.then (function (file) { 
    file.destroyRecord().then(function(){ 
     self.get('model').removeObject(file); 
    }); 
    }); 
} 

请注意,你不必做this.store.find()首先,你可以简单地做到以下几点:

removeFile: function() { 
    var self = this; 
    var fileToRemove = this.get('fileToRemove'); 
    fileToRemove .destroyRecord().then(function(){ 
    self.get('model').removeObject(file); 
    }); 
} 

但是,我选择保守,并仔细检查商店。这对我来说似乎更安全。