Вычисленное свойство EmberJS на основе массива не работает

У меня есть контроллер EmberJS со следующим вычисляемым свойством:

hasSelectedRequirements: Ember.computed('selectedRequirements.[]', function()    {
    console.log("this should get printed but it doesn't");
    return this.get('selectedRequirements').length > 0;
}),

который устанавливает логический флаг, который я использую в шаблоне для условного отображения html.

У меня также есть кнопка, которая при нажатии принимает данные формы и помещает элемент в массив selectedRequirements, вызывая действие addRequirement

actions: {
    addRequirement() {
        ...
        // extract data from form and create the requirement variable

        var selectedRequirements = this.get('selectedRequirements');
        selectedRequirements.push(requirement);
        this.set('selectedRequirements', selectedRequirements);

        console.log(this.get('selectedRequirements')); // does print as expected
    }
}

Если вместо этого я изменю функцию addRequirement на this, то обработчик функции вычисляемого свойства hasSelectedRequirements будет запущен, как ожидалось, и оператор console.log будет работать:

actions: {
    addRequirement() {
        ...
        // extract data from form and create the requirement variable

        var selectedRequirements = this.get('selectedRequirements');
        selectedRequirements.push(requirement);

        // create a new, local array
        var arr = new Array();
        arr.push(1);

        this.set('selectedRequirements', arr);

        console.log(this.get('selectedRequirements')); // does print as expected
    }
}

Кажется, что вычисляемые свойства Ember полагаются на наблюдаемый массив, являющийся совершенно другим массивом?

Проблема в том, что вычисляемое свойство не распознает, что элемент был добавлен в массив selectedRequirements, а функция вычисляемого свойства никогда не вызывается (оператор console.log никогда не запускается). Почему вычисляемое свойство не распознает, что массив selectedRequirements был изменен, и как исправить код вычисленного свойства?


person lkgarrison    schedule 07.07.2016    source источник
comment
Почему бы тебе просто не использовать hasSelectedRequirements: Ember.computed.bool('selectedRequirements.length')? Кстати, используйте pushObject, а не push.   -  person    schedule 07.07.2016


Ответы (3)


Используйте pushObject как this.get('selectedRequirements').pushObject(obj);

person Ebrahim Pasbani    schedule 07.07.2016
comment
Метод pushObject в классе Ember MutableArray - это именно то, что я искал. Я не могу сказать вам, как долго я искал и не нашел ответа на эту проблему. Я знал, в чем была основная проблема, но не знал решения Ember. Надеюсь, этот пост поможет другим. - person lkgarrison; 07.07.2016
comment
@lkgarrison Круто. Поэтому, если проблема будет решена, примите мой пост в качестве ответа. - person Ebrahim Pasbani; 07.07.2016

Кажется, что вычисляемые свойства Ember (по крайней мере, наблюдая с использованием синтаксиса array. []) Требуют нового массива для распознавания изменений. Таким образом, лучшее решение, которое я нашел, - это создать копию массива с помощью slice:

actions: {
    addRequirement() {
        ...
        // extract data from form and create the requirement variable

        var selectedRequirements = this.get('selectedRequirements');
        selectedRequirements.push(requirement);
        this.set('selectedRequirements', selectedRequirements.slice(0));

        console.log(this.get('selectedRequirements')); // does print as expected
    }
}

Это гарантирует, что вычисляемое свойство hasSelectedRequirements устанавливается соответствующим образом каждый раз, когда вызывается действие addRequirement.

person lkgarrison    schedule 07.07.2016

использование pushObject вместо push и removeObject вместо splice вызовет свойство computed.

person Krishna Prasad P V V    schedule 14.12.2020