使用 jQuery UI 对 Ember.js 项目进行排序后,使用 Ember Data 的 model.deleteRecord() 不起作用 [英] After using jQuery UI to sort an Ember.js item, using Ember Data's model.deleteRecord() doesn't work

查看:23
本文介绍了使用 jQuery UI 对 Ember.js 项目进行排序后,使用 Ember Data 的 model.deleteRecord() 不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用带有 Ember.js 的 jQuery UI Sortable 对项目列表进行排序,它似乎工作得很好,直到我删除其中一个 Ember Data 记录.模型被正确删除,但 UI 不会更新以反映这一点.如果删除最后一条记录,则会引发索引超出范围错误.如果删除中间记录,则之后 的记录将从 DOM 中删除.如果您删除第一条记录,它会从 DOM 中删除第一条和第二条记录.什么给?

给定以下把手:

<script type="text/x-handlebars" data-template-name="index">{{#每个模型}}{{render 'formField' this}}{{/每个}}<script type="text/x-handlebars" data-template-name="formField"><div class="form-field" {{bind-attr data-id=id}}><span class="delete" {{action 'delete'}}>X</span>{{name}} ({{displayOrder}})<span class="handle">#</span>

以及以下 JavaScript:

App.IndexController = Ember.ArrayController.extend({sortProperties: ['displayOrder'],//强制按 displayOrder 排序,而不是 ID更新位置:函数(位置数据){this.propertyWillChange('content');//手动通知 Emberthis.get('content').forEach(function(formField) {var key = formField.get('id');formField.set('displayOrder', positionData[key] + 1);});this.propertyDidChange('content');//手动通知 Ember}});App.IndexView = Ember.View.extend({句柄排序:函数(事件,用户界面){var positionData = {};this.$(".form-field").each(function(index, element){//从模板中的 bind-attr 获取模型 IDvar key = $(element).data('id');位置数据[键] = 索引;});this.get('controller').updatePositions(positionData);//延迟重新创建可排序的Ember.run.next(function(){ this.makeSortable(); }.bind(this));},makeSortable: Ember.on('didInsertElement', function(){尝试 {this.$().sortable("销毁");}赶上(错误){window.console.warn('没有可排序的销毁', err);}最后 {this.$().sortable({句柄:'.句柄',轴:'y',更新:this.handleSort.bind(this)});}})});App.FormFieldController = Ember.ObjectController.extend({动作:{删除":函数(){window.console.log('删除记录', this.get('name'));this.get('model').deleteRecord();}}});

这是一个小提琴.

解决方案

诀窍在于使用 sortProperties{{#each model}}>{{#每个内容}}.sortProperties 方法实际上并不安排contentmodel,它安排了arrangedContent.通过将其更改为 {{#eachlocatedContent}},您的问题就会消失,因为 DOM 排列将与您的模型排列保持同步.

I'm using jQuery UI Sortable with Ember.js to sort a list of items, and it seems to work great, until I go to delete one of the Ember Data records. The model is deleted properly, but the UI doesn't update to reflect that. If you delete the last record, an Index Out of Range error is thrown. If you delete a middle record, the one after it is removed from the DOM. If you delete the first record, it removes the first and second one from the DOM. What gives?

Given the following Handlebars:

<script type="text/x-handlebars" data-template-name="application">
    <h1>Ember Data + jQueryUI Sortable Problems</h1>
    {{outlet}}
    Try sorting and then deleting something. The model is deleted properly, but the DOM does not reflect that. Sometimes it stays in the DOM, sometimes the wrong one is deleted, and sometimes both the right and a wrong one is deleted.
</script>
<script type="text/x-handlebars" data-template-name="index">
    {{#each model}}
        {{render 'formField' this}}
    {{/each}}
</script>
<script type="text/x-handlebars" data-template-name="formField">
    <div class="form-field" {{bind-attr data-id=id}}>
        <span class="delete" {{action 'delete'}}>X</span>
        {{name}} ({{displayOrder}})
        <span class="handle">#</span>
    </div>
</script>

And the following JavaScript:

App.IndexController = Ember.ArrayController.extend({
    sortProperties: ['displayOrder'], // Force sort by displayOrder, not ID
    updatePositions : function(positionData){
          this.propertyWillChange('content'); // Manually notify Ember
          this.get('content').forEach(function(formField) {
              var key = formField.get('id');
              formField.set('displayOrder', positionData[key] + 1);
          });
          this.propertyDidChange('content'); // Manually notify Ember
      }
    });

App.IndexView = Ember.View.extend({
    handleSort: function(event,ui){
        var positionData = {};
        this.$(".form-field").each(function(index, element){
            // Get model ID from bind-attr in template
            var key = $(element).data('id');
            positionData[key] = index;
        });
        this.get('controller').updatePositions(positionData);
        // Delay recreating the sortable
        Ember.run.next(function(){ this.makeSortable(); }.bind(this));
    },
    makeSortable: Ember.on('didInsertElement', function(){
        try {
            this.$().sortable("destroy");
        } catch(err){ 
            window.console.warn('No sortable to destroy', err);
        }
        finally {
            this.$().sortable({
                handle: '.handle',
                axis: 'y',
                update: this.handleSort.bind(this)
            });
        }
    })
});

App.FormFieldController = Ember.ObjectController.extend({
    actions: {
        'delete': function() {
            window.console.log('deleting record', this.get('name'));
            this.get('model').deleteRecord();
        }
    }
});

Here's a fiddle.

解决方案

The trick is in your use of sortProperties and {{#each model}} or {{#each content}}. The sortProperties method does not actually arrange content or model, it arranges arrangedContent. By changing it to {{#each arrangedContent}}, your problems disappear because the DOM arrangement will stay in sync with your model arrangement.

这篇关于使用 jQuery UI 对 Ember.js 项目进行排序后,使用 Ember Data 的 model.deleteRecord() 不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆