javascript Ember 计算属性未更新

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21562496/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-27 21:11:33  来源:igfitidea点击:

Ember computed property not being updated

javascriptember.js

提问by Nathan Lutterman

I'm not too entirely sure why my computed property isn't returning updated values.

我不太确定为什么我的计算属性没有返回更新的值。

I have a list of options that a user can click through, and the action updates a property, which is an Ember Object, for the controller. I have a computed property that loops through the object, looks for keys that have non-null values for that Ember Object property, and if it does find one, returns false, otherwise true.

我有一个用户可以单击的选项列表,并且该操作会更新控制器的属性,即 Ember 对象。我有一个循环遍历对象的计算属性,为该 Ember 对象属性查找具有非空值的键,如果确实找到了一个,则返回 false,否则返回 true。

Here's the stuff:

这是东西:

App.SimpleSearch = Ember.Object.extend({
    init: function() {
        this._super();

        this.selectedOptions = Ember.Object.create({
            "Application" : null,
            "Installation" : null,
            "Certification" : null,
            "Recessed Mount" : null,
            "Width" : null,
            "Height" : null,
            "Heating" : null,
            "Power" : null
        });
    },

    selectedOptions: {},

    numOfOptions: 0,

    allOptionsSelected: function() {
        var selectedOptions = this.get('selectedOptions');
        for (var option in selectedOptions) {
            console.log(selectedOptions.hasOwnProperty(option));
            console.log(selectedOptions[option] === null);
            if (selectedOptions.hasOwnProperty(option)
                && selectedOptions[option] === null) return false;
        }
        return true;
    }.property('selectedOptions')
});


App.SimpleSearchRoute = Ember.Route.extend({
    model: function() {
        return App.SimpleSearch.create({
            'SimpleSearchOptions': App.SimpleSearchOptions,
            'numOfOptions': App.SimpleSearchOptions.length
        });
    },
    setupController: function(controller, model) {
        controller.set('model', model);
    }
});


App.SimpleSearchController = Ember.ObjectController.extend({
    getProductsResult: function() {
        var productsFromQuery;
        return productsFromQuery;
    },

    setSelection: function (option, selectionValue) {
        this.get('selectedOptions').set(option, selectionValue);
        this.notifyPropertyChange('allOptionsSelected');
    },

    actions: {
        registerSelection: function(option) {
            console.log('registering selection');
            console.log(this.get('allOptionsSelected'));
            console.log(this.get('selectedOptions'));
            this.setSelection(option.qname, option.value);
        },

The action in the controller, registerSelectionis firing just fine, but I only see the console.logfrom the SimpleSearchmodel once. Once the property is computed that first time, it isn't paid attention to after that, which means that the computed property isn't observing the changes to selectedOptionswhenever this is called:

控制器中的动作registerSelection触发得很好,但我只console.logSimpleSearch模型中看到了一次。一旦第一次计算属性,之后就不会受到关注,这意味着计算属性不会在selectedOptions调用 this 时观察更改:

setSelection: function (option, selectionValue) {
    this.get('selectedOptions').set(option, selectionValue);
    this.notifyPropertyChange('allOptionsSelected');
},


Edit:

编辑:

I actually solved my issue without changing anything.

我实际上在没有改变任何东西的情况下解决了我的问题。

I've changed the following line:

我更改了以下行:

this.notifyPropertyChange('allOptionsSelected');

to:

到:

this.get('model').notifyPropertyChange('selectedOptions');

notifyPropertyChangeneeds to be called within the context of the model (or the Ember Object that has observers of a specific property), and the string sent as an argument is the name of the property that was updated.

notifyPropertyChange需要在模型(或具有特定属性观察者的 Ember 对象)的上下文中调用,并且作为参数发送的字符串是被更新的属性的名称。

After I made that change, it worked as intended.

在我进行更改后,它按预期工作。

回答by Kingpin2k

Ember doesn't observe objects for any change on the object, it observes a single property.

Ember 不观察对象的任何变化,它观察单个属性。

How is this affecting you? Well in this method you are watching selectedOptions, but that object itself is still the same object, you might be changing properties on it, but not the object itself. And then you are telling Ember in the scope of the controller that allOptionsSelectedhas changed, so it regrabs it, but it doesn't recalculate it because it's not dirty, it just changed. You'd really want to say selectedOptionshas changed to get allOptionsSelectedto recalculate its value. Unfortunately you're doing this in the scope of the controller, so telling the controller that property has changed doesn't matter to it.

这对你有什么影响?好吧,在这个方法中,您正在观察selectedOptions,但该对象本身仍然是同一个对象,您可能会更改其属性,但不会更改对象本身。然后你告诉 Ember 在allOptionsSelected已经改变的控制器范围内,所以它重新抓取它,但它不会重新计算它,因为它不是脏的,它只是改变了。你真的想说selectedOptions已经改变allOptionsSelected了重新计算它的价值。不幸的是,您是在控制器的范围内执行此操作,因此告诉控制器属性已更改对其无关紧要。

allOptionsSelected: function() {
  var selectedOptions = this.get('selectedOptions');
  for (var option in selectedOptions) {
     console.log(selectedOptions.hasOwnProperty(option));
     console.log(selectedOptions[option] === null);
     if (selectedOptions.hasOwnProperty(option)
        && selectedOptions[option] === null) return false;
     }
  return true;
}.property('selectedOptions')

Here's a dummy example showing what things cause it to actually update.

这是一个虚拟示例,显示是什么原因导致它实际更新。

http://emberjs.jsbin.com/iCoRUqoB/1/edit

http://emberjs.jsbin.com/iCoRUqoB/1/edit

Honestly since you're not watching particular properties I'd probably do an array, or create a method on the object that handles adding/removing/modifying the properties so you could fire from within it's scope a property change updating all parent listeners with the changes.

老实说,由于您没有查看特定的属性,我可能会做一个数组,或者在处理添加/删除/修改属性的对象上创建一个方法,这样您就可以从它的范围内触发属性更改,更新所有父级侦听器变化。

回答by Ganesh Arulanantham

Ember computed property dependent keys can be a

Ember 计算属性相关键可以是

  1. property key. in example: 'jobTitle'
  2. computed property key. in example: 'companyName'
  3. property key of an object. in example: 'salesAccount.name and salesAccount.website'
  1. 属性键。例如:'jobTitle'
  2. 计算属性键。例如:“公司名称”
  3. 对象的属性键。例如:“salesAccount.name 和 salesAccount.website”

Example extracted from Ember.model definition:

从 Ember.model 定义中提取的示例:

...
   jobTitle : DS.attr('string'),
   salesAccount: belongsTo('salesAccount'),

   companyName: Ember.computed('jobTitle', 'salesAccount.name', {
    get: function () {
      return this.get('salesAccount.name');
    }
  }),

  companyWebsite: Ember.computed('salesAccount.website', 'companyName',  {
    get: function () {
      return this.get('salesAccount.website');
    }
  })
...