如何孤立地在组件中使用模型,但如何维护模型更新的单向绑定?

时间:2019-01-16 13:34:45

标签: ember.js

我目前有一个组件,该组件根据传递给它的模型显示结果表:

\\pagedContent is a computed property of the model
{{table-test model=pagedContent}}

当通过查询参数选择各种过滤器时,表将更新其内容。我蜂试图用以下代码对表标题实施一些“单击时排序”行为:

    import Component from '@ember/component';
    import {
      computed
    } from '@ember/object';

    export default Component.extend({

      model: null,
      init() {
        this._super(...arguments);
        this.dataSorting = ['total_users']
        this.dataSortingDesc = ['total_users:desc']
      },

      sortedDataDesc: computed.sort('unsortedData', 'dataSortingDesc'),
      sortedData: computed.sort('unsortedData', 'dataSorting'),
      unsortedData: computed('model', function () {
        return this.get('model');
      }),

      actions: {
        columnsort(property) {
          if (!this.get('tableSorted')) {

            this.set('dataSortingDesc', [`${property}:desc`])
            this.set('model', this.get('sortedDataDesc'))
            this.set('tableSorted', true)

          } else {
            this.set('dataSorting', [property])
            this.set('displayModel', this.get('sortedData'))
            this.set('model', null)
          }
        },
      }
    });

排序工作正常,但是由于模型的双向绑定,我遇到了问题。模板上的其他组件也使用该模型,并且在对表中的数据进行排序时,这些组件会产生各种问题。

我尝试使用如下所示的计算属性来创建模型的单独“副本”:

  \\a new property
  displayModel: computed('model', function () {
    return this.get('model');
  }),
  sortedDataDesc: computed.sort('unsortedData', 'dataSortingDesc'),
  sortedData: computed.sort('unsortedData', 'dataSorting'),
  unsortedData: computed('model', function () {
    return this.get('model');
  }),

  actions: {
    columnsort(property) {
      if (!this.get('tableSorted')) {

        this.set('dataSortingDesc', [`${property}:desc`])
        this.set('model', this.get('sortedDataDesc'))
        this.set('tableSorted', true)

      } else {
        this.set('dataSorting', [property])
        this.set('displayModel', this.get('sortedData'))
        this.set('model', null)
      }
    },

该表然后在displayModel上进行迭代以创建自己。这会产生一种行为,即列进行排序,但是一旦单击列标题,显示就会“冻结”,并且不会随着基础模型的更新而更新。在这种情况下,我可以从其他组件中看到,随着应用新的过滤器,模型会继续更新。

我还没有使用oneWaydidUpdateAttrs实现。

如何在组件中创建model的副本,以便可以对表列进行排序,而无需通过双向绑定更改整个模型,同时保持单向绑定,以便更新模型通过父模板,它还会在组件中更新吗?

编辑:

我创建了一个旋转的here

如果单击表的标题,您会看到两个组件都更改了顺序,因为我正在处理传递的“模型”。

我要实现的工作流程是,可以将模型传递到表组件中,以便它显示数据,并且可以对列进行排序,而不会影响第二个组件(也由模型提供)。

问题是我还需要填充表的属性来刷新(如果父模板上存在一组其他过滤器)通过父模板上的交互来刷新模型。

因此,“排序”会影响填充表的属性,但除此之外,填充表的属性对托管组件的父级上的模型更新很敏感。

1 个答案:

答案 0 :(得分:1)

这里的问题是,您要共享组件之间支持模型的数组,然后操纵该数组(Ember知道)。如果您停止共享数组(通过将引用复制到另一个数组):

import Ember from 'ember';

export default Ember.Route.extend({
  model(){
    return [{name: "Frank", age: 22}, {name: "Alan", age: 43}, {name: "Bob", age: 56}] 
  },
  setupController(controller, model){
    controller.set('model', model);
    controller.set('tableModel', model.slice(0));
  }
});

然后像这样application.hbs来更改您的名字:

{{my-component model=tableModel}}
{{second-component model=model}}

您只会看到表格组件顺序发生的更改。由于两个数组都指向相同的引用,因此您的模型本身也绑定到两个数组(即更改模型属性,例如age会影响modeltableModel,因为它们实际上都指向相同的引用内存,但是排序只会影响tableModel,因为您已经分配了两个数组

我用my own copy扩展了要点,其中我操纵了models数组中的引用模型,由于基本元素的存在,它同时影响了modelstableModels数组中的引用相同。