gpt4 book ai didi

jquery - 解决 Ember 和 Dragula 的 DOM View

转载 作者:行者123 更新时间:2023-12-03 22:27:50 26 4
gpt4 key购买 nike

我正在使用 Dragula 在 Ember 中创建一组拖放组件。我将项目列表传递给包含多个可放置存储桶的父包装器。该项目列表最初会被过滤,以便将正确的项目呈现在正确的存储桶中。然后将 Dragula 连接起来,以便可以拖放项目。当发生 drop 事件时,我尝试更新底层 Ember 对象。这可能会导致重新应用过滤器并发生一些渲染。问题是 DOM 已被 Dragula 操纵,与 Ember 认为的不一样,DOM 节点就消失了。

当 Ember 和 Dragula 都认为自己拥有 DOM 及其当前表示时,我怎样才能让他们表现得很好?我尝试取消拖放事件,然后让 Ember 设置值,但效果有限。

dnd-wrapper/template.hbs

{{yield (action "register")}}

dnd-wrapper/component.js

export default Ember.Component.extend({
drake: null,
buckets: [],
items: [],
initDragula: Ember.on('willInsertElement', function() {
this.set('drake', window.dragula());
}),
setupDragulaEvents: Ember.on('didInsertElement', function() {
this.get('drake').on('drop', (itemEl, destinationEl, sourceEl) => {
let dest = this.buckets.findBy('element', destinationEl);
let source = this.buckets.findBy('element', sourceEl);
let item = this.items.findBy('element', itemEl);

item.component.set('item.bucket', dest.component.get('value'));
});
}),
actions: {
register(type, obj) {
if(type === 'bucket') {
this.get('drake').containers.push(obj.element);
this.buckets.pushObject(obj);
}
else {
this.items.pushObject(obj);
}
}
}
});

dnd-bucket/template.hbs

<h2>bucket {{value}}</h2>
<ul>
{{#each filteredItems as |item|}}
{{dnd-item item=item register=register}}
{{/each}}
</ul>

dnd-bucket/component.js

export default Ember.Component.extend({
items: null,
registerWithWrapper: Ember.on('didInsertElement', function() {
this.register('bucket', {
component: this,
element: this.$('ul')[0]
});
}),
filteredItems: Ember.computed('items.@each.bucket', function() {
return this.get('items').filterBy('bucket', this.get('value'));
})
});

dnd-item/template.hbs

{{item.title}}

dnd-item/component.js

export default Ember.Component.extend({
registerWithWrapper: Ember.on('didInsertElement', function() {
this.register('item', {
component: this,
element: this.$()[0]
});
})
});

在线演示:http://ember-twiddle.com/c086d2853a926c310a23

GitHub 演示:https://github.com/RyanHirsch/dragula-ember-example

最佳答案

我遇到了与您描述的完全相同的问题。我花了几个小时尝试不同的方法来解决这个问题,我想我终于想出了一个虽然简单但可行的解决方案。其核心是我必须在触发 drop 事件后强制“源”存储桶重新渲染其项目。

不幸的是,我必须使用蛮力才能使重新渲染正常工作,在任何父 View 上调用重新渲染都不起作用。 Ember 认为从 DOM 中消失的项目仍然存在并且正确呈现。

我最终使用{{#if listVisible}}{{/if}}将filteredItems列表包装在dnd-bucket模板中。如果您随后将 itemsVisible 设置为 false 和 true,它会强制列表重新渲染并修复 DOM 损坏。我还必须确保这些集合在运行循环中渲染之前和之后。

resetView: function() {
Ember.run.scheduleOnce('render', this, () => {
this.set("listVisible", false);
});
Ember.run.scheduleOnce('afterRender', this, () => {
this.set("listVisible", true);
});
}

就我而言,我在更新 drop 回调中的模型后触发了 ResetView。虽然这个修复很hacky,但视觉结果是可以接受的。如果 DOM 元素确实消失了,它们就会被替换,这有点不和谐。但在 99.9% 的情况下,当没有 DOM 元素丢失时,根本不存在视觉故障。

关于jquery - 解决 Ember 和 Dragula 的 DOM View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32587495/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com