最初由@andrewsydGitHub上询问。


  对于嵌套列表,是否可以在dragEnd动作中确定项目已放入哪个“子列表”? (例如,班级名称,ID等)
  
  在我的场景中,我正在对可以彼此属于的余烬数据记录(即嵌套的“树”结构)进行排序。当我将一个嵌套记录“拖到”另一个记录中(使拖拽的记录成为第二个记录的子记录)时,我需要更新ember-data中的parent属性。我的问题是,如何将第二条记录(新的父项)的某些ID传递给dragEnd动作?
  
  这有可能吗?

最佳答案

解决方案0:调整数据模型以将isParent属性转换为派生值而不是真值源

首先,拥有必须手动更新的isParent属性是一种有缺陷的方法。

如果您将isParent状态作为属性,并且要求前端对其进行更新,则您有两个可以(并最终会)不同步的事实来源。考虑到用户可以篡改对您的API后端的网络请求,因此尤其如此。

isParent应该从孩子的数量推断出来。它可以是一个简单的计算属性:

{
  isParent: computed('children.[]', function () {
    return this.get('children.length') > 0
  }
}


可以在后端使用类似的方法。

如果您不控制后端,但仍然需要从前端更新isParent属性,建议您在序列化过程中修改序列化器,以将isParent计算出的属性值包括到有效负载中。

尽管我坚信您应该使用此解决方案,但我在下面研究了几个替代解决方案。

解决方案1:使用观察者自动更新父状态

在您的模型中:

{
  updateParentState: Ember.observer('children.[]', function () {
   const isParent = this.get('children.length') > 0
    this.setProperties({isParent})
  })
}


每当更新时,这将使isParent属性与其children关系保持同步。

这是一个演示:https://ember-twiddle.com/f1c737d3bc106cb9cca071fd01fe334f?openFiles=models.item.js%2C

请注意,如果在拖尾自动保存记录,则应将保存包装到Ember.run.next中,以便在观察者触发后进行保存。

解决方案2:访问已拖动项目的新旧父项

假设您已建立如下关系:

export default Model.extend({
  isParent: attr('boolean'),
  parent: belongsTo('item', {inverse: 'children'}),
  children: hasMany('item', {inverse: 'parent'}),
})


...您可以在拖动结束操作中访问被拖动项的新旧父项!

{
  actions : {
    dragEnd ({sourceList, sourceIndex, targetList, targetIndex}) {
      if (sourceList === targetList && sourceIndex === targetIndex) return

      const draggedItem = sourceList.objectAt(sourceIndex)
      const oldParent = draggedItem.get('parent')                     // <--

      sourceList.removeAt(sourceIndex)
      targetList.insertAt(targetIndex, draggedItem)

      const newParent = draggedItem.get('parent')                     // <--

      newParent.set('isParent', newParent.get('children.length') > 0) // <--
      oldParent.set('isParent', oldParent.get('children.length') > 0) // <--
    },
  }
}


我已经用箭头注释标记了相关的行。

看,您在移动之前从拖动的项目中读取了旧的父项。移动项目后,您将阅读新的父项。这是可能的,因为Ember Data自动执行关系簿记。

最后,您更新父母双方的isParent状态。

演示:https://ember-twiddle.com/ab0bfdce6a1f5ad4bd0d1c9c45f642fe?openFiles=controllers.application.js%2Ctemplates.components.the-item.hbs

10-05 23:14