Ember.js更新模型属性

ktca8awb  于 2022-11-05  发布在  其他
关注(0)|答案(1)|浏览(174)

我对ember.js的工作原理还不是很了解。(一个字符串数组)。到目前为止,除了更新的features属性没有保存外,其他一切似乎都正常。当我单击复选框时,它会更新multi-select-checkboxes组件中选定的计算属性。我想如果我将model.owner.features作为selected传递给组件,那么当组件发生变化时,它会直接更新模型。

(function() {
  const { shroud } = Sw.Lib.Decorators;

  Sw.FranchisorNewAnalyticsConnectionsUsersRoute = Ember.Route.extend({
    currentFranchisorService: Ember.inject.service('currentFranchisor'),

    @shroud
    model({ account_id }) {
      console.log("load model in route")
      return Ember.RSVP.hash({
        account: this.get('store').find('account', account_id),
        owners: Sw.AccountOwner.fetch(account_id),
        newAccountOwner: Sw.AccountOwner.NewAccountOwner.create({ accountID: account_id }),
      });
    },

    actions: {
      @shroud
      accountOwnersChanged() {
        this.refresh();
      },

      close() {
        this.transitionTo('franchisor.newAnalytics.connections');
      },
    },
  });
})();

用户控制器:

(function() {
  const { shroud, on, observer } = Sw.Lib.Decorators;
  Sw.FranchisorNewAnalyticsConnectionsUsersController = Ember.Controller.extend(Sw.FranchisorControllerMixin, {
    isAddingUser: false,

    adminOptions: [{
      label: 'Employee Advocacy',
      value: 'employee advocacy'
    }, {
      label: 'Second Feature',
      value: 'other'
    }, {
      label: 'Can edit users?',
      value: 'edit_users'
    }],

  });
})();

users.handlebars

{{#each model.owners as |owner|}}
   <tr
    <td>
     {{owner.name}}
    </td>
    <td>
     {{owner.email}}
    </td>
    <td>{{if owner.confirmedAt 'Yes' 'No'}}</td>
    <td>
      {{log 'owner.features' owner.features}}
      {{multi-select-checkboxes 
         options=adminOptions 
         selected=owner.features
         owner=owner
         model=model
       }}
     </td>
     <td>
       <button class="btn light-red-button" 
         {{action "remove" owner}}>
         Remove
       </button>
     </td>
   </tr>
 {{/each}}

multi-select-checkboxes.handlebar:

{{#each checkboxes as |checkbox|}}
  <p>
    <label>
      {{input type='checkbox' checked=checkbox.isChecked}}
      {{checkbox.label}}
    </label>
  </p>
{{/each}}

多选择复选框.jsx:

// Each available option becomes an instance of a "MultiSelectCheckbox" object.
var MultiSelectCheckbox = Ember.Object.extend({
  label: 'label',
  value: 'value',
  isChecked: false,

  changeValue: function () { },
  onIsCheckedChanged: Ember.observer('isChecked', function () {
    var fn = (this.get('isChecked') === true) ? 'pushObject' : 'removeObject';
    this.get('changeValue').call(this, fn, this.get('value'));
  })
});

Sw.MultiSelectCheckboxesComponent = Ember.Component.extend({
  labelProperty: 'label',
  valueProperty: 'value',
  // The list of available options.
  options: [],
  // The collection of selected options. This should be a property on
  // a model. It should be a simple array of strings.
  selected: [],
  owner: null,
  model: null,
  checkboxes: Ember.computed('options', function () {
      console.log("CHECKBOXES", this.get('model'))
    var _this = this;
    var labelProperty = this.get('labelProperty');
    var valueProperty = this.get('valueProperty');
    var selected = this.get('selected'); 
    var model = this.get('model'); 
    return this.get('options').map(function (opt) {
      var label = opt[labelProperty];
      var value = opt[valueProperty];
      var isChecked = selected.contains(value);
      return MultiSelectCheckbox.create({
        label: label,
        value: value,
        isChecked: isChecked,
        model: model,
        changeValue: function (fn, value, model) {
          _this.get('selected')[fn](value);
          console.log("model in middle", this.get('model'))
          this.get('model').save();
        }
      });
    });
  }),
  actions: {
    amountChanged() {
      const model = this.get(this, 'model');
      this.sendAction('amountChanged', model); 
    }
  }
});
agxfikkp

agxfikkp1#

看起来你对我有一个相当不错的理解!我认为你的实现只是在这里或那里缺少了一个东西,可能比它必须的要复杂一点。
这里有一个Twiddle,它可以满足您的要求。我将模型上的属性命名为attrs,以避免可能的混淆,因为attributes与一些模型方法(如rollbackAttributes()changedAttributes())一起使用。
需要注意的事项:
1.创建复选框对象列表时,不需要指定changeValue函数。onIsCheckedChanged观察器应该负责更新模型的属性。在多选复选框中Mapoptions时,只需将您想要更新的模型或其属性(字符串数组)传递到每个复选框中:

return Checkbox.create({
  label: option.label,
  value: option.value,
  attributes: this.get('owner.attrs') // this array will be updated by the Checkbox
});

1.如果您检索的模型在此数组中没有任何数据,Ember Data将保留属性为undefined,因此直接在数组上进行更新将导致错误(例如,cannot read property 'pushObject' of undefined),因此请确保在此组件允许用户更新值之前将属性设置为数组。
1.观察器将同步触发,因此将其 Package 在Ember.run.once()中可能是值得的(不确定您还将对该组件/模型执行什么操作,因此为了完整起见,我注意到了这一点)。
1.如果你想自动保存对模型的修改,你需要在更新后调用.save(),在这种情况下,我会把模型传递到每个复选框,并在修改后调用save。

相关问题