用余烬排序jQuery UI后删除项目



我使用jQuery UI可排序Ember,它工作得很好,直到我想在排序后删除一些项目。这个问题已经在stackoverflow上回答了,但这个解决方案不适合我。我用的是Ember 2.6。

组件模板
<ui id="department_roles">
    {{#each sortedList as |item|}}
        {{item.id}}
            <li data-id="{{item.id}}"  role_id="{{item.id}}" class="ui-state-default role_droppable">
                <span>
                    {{item.name}}
                </span>
                <button {{action "removeItem" item.id}}>Remove</button>
            </li>
    {{/each}}
</ui>

组件,排序工作良好,删除操作项后从数组中删除,但DOM是不正确的。

    import Ember from 'ember';
export default Ember.Component.extend({
    list: Ember.ArrayProxy.create({content: Ember.A()}),
    init: function () {
        this._super();
        this.get('list').pushObject({
            id: 1,
            index: 1,
            name: 'name1'
        });
        this.get('list').pushObject({
            id: 2,
            index: 2,
            name: 'name2'
        });
        this.get('list').pushObject({
            id: 3,
            index: 3,
            name: 'name3'
        });
        this.get('list').pushObject({
            id: 4,
            index: 4,
            name: 'name4'
        });
        this.get('list').pushObject({
            id: 5,
            index: 6,
            name: 'name5'
        });
    },
    sortProps: ['index:asc'],
    sortedList: Ember.computed.sort('list', 'sortProps'),
    updateSortedOrder(indices) {
        this.beginPropertyChanges();
        let tracks = this.get('list').forEach((item) => {
            var index = indices[Ember.get(item, 'id')];
            if (Ember.get(item, 'index') !== index) {
                Ember.set(item, 'index', index);
            }
        });
        this.endPropertyChanges();
    },
    didRender: function () {
        this._super();
        var self = this;
        Ember.$("#department_roles").sortable({
            update: function () {
                var indices = {};
                Ember.$(this).children().each((index, item) => {
                    indices[Ember.$(item).data('id')] = index + 1;
                });
                self.updateSortedOrder(indices);
            },
        });
        Ember.$('#department_roles').disableSelection();
    },
    actions: {
        removeItem: function (itemId) {
            var self = this,
                deleteItem,
                list = this.get('list');
            this.$("#department_roles").sortable("destroy");
            list.arrayContentWillChange();
            list.forEach(function (item) {
                if (item.id === itemId) {
                    deleteItem = item;
                }
            });
            list.removeObject(deleteItem);
            list.arrayContentDidChange();
            Ember.$("#department_roles").sortable({
                update: function () {
                    var indices2 = {};
                    Ember.$(this).children().each((index, item) => {
                        indices2[Ember.$(item).data('id')] = index + 1;
                    });
                    self.updateSortedOrder(indices2);
                },
            });
            console.log(self.get('sortedList'));
        }
    }
});

我仍然没有完美的解决方案,但因为@Aamir Mahmood在评论中要求更新,我将把我的解决方案放在这里,不完美,但现在它工作。

我尝试了我认为每一个可能的解决方案,总是相同的结果,DOM已经打破后一个元素被删除并添加到另一个列表。break并不总是发生在第一次排序之后,但最终还是会发生。

首先我会写我所做的尝试,有一些解决方案在网络上工作的烬的以前的版本,但版本2.0后,解决方案不再工作了。
1)使用组件功能渲染后更新不工作
2)更新后的排序索引也不工作
3)使用值为true/false的计算属性,更新完成后将属性设置为false并立即更改为true不起作用

解决方案是完全删除html ul标签,并重新将其重写为DOM,所有其他解决方案都没有这样做。

我的解决方案是创建计算属性,即数组和只添加一个项目到数组和更新后设置新的数组计算属性。更新后,数组循环将运行,旧的ul标签将被删除,新的将被添加。

模板:

{{#each placeboListComputed as |placeboItem|}}
<ul id="sortable_{{node.id}}" class="sortable_connection">
    {{#each sortedList key="index" as |item index|}}
        {{li-component
        item=item
        index=index
        }}
    {{/each}}
</ul>
{{/each}}

组件,

这不是工作的代码,这只是一个例子,以获得想法。Placebo list是一个计算属性,它是一个数组每当数组被改变时就会循环所以模板会呈现DOM

从一个列表排序到另一个列表后,第一个被触发更新的列表上的项目将从另一个列表接收,然后删除,最后更新列表上的获取项目。因此,在删除项目后,我将该项目保存到垃圾箱,在更新时,我检查给定的项目是否不存在于列表中,但存在于垃圾箱中,我将该项目添加到列表中,并使用计算属性重写内容。

export default Ember.Component.extend({
sortProps: ['index:asc'],
sortedList : Ember.computed.sort('list', 'sortProps'),
placeboList: Ember.A(),
placeboListComputed: Ember.computed('placeboList', function () {
    return this.get('placeboList');
}),
init() {
    this._super();
    this.resetPlacebo();
},
resetPlacebo() {
    var list = Ember.A(),
        newPlacebo = Placebo.create();
    list.pushObject(newPlacebo);
    this.set('placeboList', list);
},
updateSortableIndices(items, indices, self) {
    self.beginPropertyChanges();
    items.forEach((item) => {
        var index = indices[Ember.get(item, 'id')];
        if (index !== undefined) {
            if (Ember.get(item, 'index') !== index) {
                Ember.set(item, 'index',index);
            }
        }
    });
    self.endPropertyChanges();
},
didRender() {
    var self = this;
    Ember.$("#sortable_" + this.get('node.id')).sortable({
        helper: 'clone',
        appendTo: "#append_element",
        connectWith: ".sortable_connection",
        update: function (event, ui) {
            var uiItemId = Ember.$(ui.item).children().attr('data-id'),
                uiItemIndex = Ember.$(ui.item).index() + 1;
            var item = self.getItem(uiItemId);
            var indices = {};
            var currentItemIndex = item.index;
            Ember.$(this).children().children().each((index, item) => {
                indices[Ember.$(item).attr('data-id')] = index + 1;
            }).promise().done(function () {
                if (!(uiItemId in indices)) {
                    var trash = self.getTrash(uiItemId);
                    if (trash !== undefined) {
                        Ember.$.each(indices, function (id, index) {
                            if (index >= currentItemIndex ) {
                                index = index + 1;
                                indices[id] = index;
                            }
                        });
                        self.removeTrash(uiItemId);
                    } else {
                        Ember.set(role, 'index', uiItemIndex);
                    }
                }
                self.updateSortableIndices(self.get('list'), indices, self);
            });
            self.resetPlacebo();
        },
        receive: function (event, ui) {
            var id = ui.item.children().attr('data-id'),
                items = self.get('list');
            var item= self.getItem(id, true);
            items.arrayContentWillChange();
            items.pushObject(item);
            items.arrayContentDidChange();
        },
        remove: function (event, ui) {
            var item= self.getItem(ui.item.children().attr('data-id')),
                items = self.get('list');
            var removedIndex = item.index;
            items .arrayContentWillChange();
            self.pushTrash(item.id, item);
            items .removeObject(item);
            self.sortRemovedIndex(items , removedIndex);
            items .arrayContentDidChange();
        }
    });
}

这还不是完全测试的解决方案,但我看到它的工作。如果有烬专家,我将很感激看到他的想法或解决这个问题。

最新更新