В Ember.js, как уведомить соответствующий элемент управления ArrayController, когда свойство в ArrayController изменяется

У меня есть EmailsController (ArrayController), в котором хранятся все электронные письма. У меня есть EmailController (ObjectController), у которого есть параметр, который сохраняет, выбран ли фактический адрес электронной почты или нет. Я пытаюсь реализовать кнопку в шаблоне электронной почты, которая выбирает или отменяет выбор всех электронных писем. Поэтому мне как-то нужно уведомить EmailController через действие EmailsController и изменить параметр isChecked EmailController.

Я пытаюсь использовать itemController, потребности и параметры controllerBinding, но ничего не работает.

Вот контроллеры:

App.EmailsController = Ember.ArrayController.extend({
    needs: ["Email"],
    itemController: 'Email',
    checkAll: true,
    actions: {
        checkAllEmails: function() {
            this.toggleProperty("checkAll");
            console.log(this.get("checkAll"));
        } 
    }
});


App.EmailController = Ember.ObjectController.extend({
    needs: ["Emails"],
    controllerBinding: 'controllers.Emails',
    isChecked: true,
    checkAllChanged: function() {
        //this should execute, but currently it does not
        this.set("isChecked",this.get('controller.checkAll'));
    }.property("controller")
});

Вот соответствующий jsFiddle: http://jsfiddle.net/JqZK2/4/ Целью будет для переключения выбора флажков с помощью кнопки «Отметить все».

Спасибо!


person gsanta    schedule 18.04.2014    source источник


Ответы (2)


Вы смешиваете несколько разных механизмов и используете несколько неправильных соглашений. Однако не всегда легко найти этот материал, так что не волнуйтесь.

Ссылки на контроллеры

Несмотря на то, что контроллеры создаются в формате верхнего регистра, они хранятся в формате нижнего регистра, и ваше свойство needs должно быть:

needs: ['emails'],

Затем вы получаете доступ к другим контроллерам через свойство controllers:

this.get('controllers.emails.checkAll')

Вычисляемые свойства

Вычисляемые свойства можно использовать как геттер/сеттер для переменной, а также как способ псевдонимов других свойств. Например, если вы хотите, чтобы свойство isChecked контроллера электронной почты было напрямую связано со значением свойства checkAll контроллера электронной почты, вы можете сделать это:

isChecked: function() {
  return this.get('controllers.emails.checkAll');
}.property('controllers.emails.checkAll')

Хотя вычисляемые свойства могут делать гораздо больше, эта базовая форма на самом деле является просто вычисляемым псевдонимом, и есть вспомогательная функция, которая упрощает его:

isChecked: Ember.computed.alias('controllers.emails.checkAll')

Наблюдаемые

Наблюдаемое в основном создает метод, который будет вызываться при изменении наблюдаемого значения. Вычисляемый псевдоним заставит все элементы снимать или проверять каждый раз, когда вы нажимаете на любой из них, поскольку их свойство isChecked напрямую связано со свойством checkAll родительского контроллера. Вместо того, чтобы ваш метод checkAllChanged идентифицировал его как свойство, он должен использовать observes:

checkAllChanged: function() {
  this.set("isChecked",this.get('controllers.emails.checkAll'));
}.observes("controllers.emails.checkAll")

Таким образом, когда свойство checkAll изменяется на родительском контроллере, этот метод обновляет свойства isChecked всех элементов до своего значения, но если вы снимите флажок или отметите отдельный элемент, это не повлияет на другие элементы.

Привязки

Привязки несколько устарели; Из чтения проблем в репозитории Ember на github я полагаю, что создатели Ember, похоже, предпочитают вместо этого использовать вычисляемые свойства, псевдонимы и наблюдаемые. Это не значит, что они не работают, и если бы ваша цель состояла в том, чтобы не вводить controllers.emails каждый раз, вы могли бы создать его, как вы это сделали (хотя я бы не назвал его контроллером, потому что это действительно довольно двусмысленно):

emailsBinding: 'controllers.emails'

Вместо этого используйте вычисляемый псевдоним:

emails: Ember.computed.alias('controllers.emails')

Затем вы можете изменить своего наблюдателя на:

checkAllChanged: function() {
  this.set("isChecked",this.get('emails.checkAll'));
}.observes("emails.checkAll")

Вот обновленная версия вашего jsFiddle: http://jsfiddle.net/tMuQn/

person Aaron Storck    schedule 18.04.2014
comment
Спасибо! Я принимаю этот ответ, потому что он многое проясняет, очень полезен. (Хотя я использовал следующее решение, потому что оно было короче и проще) - person gsanta; 18.04.2014

Вы можете просто перебирать электронные письма, изменяя их свойства из родительского контроллера. Вам не нужно указывать needs или наблюдать за переменной.

App.EmailsController = Ember.ArrayController.extend({
    itemController: 'email',
    actions: {
      checkAllEmails: function() {
        this.forEach(function(email) {
          email.toggleProperty("isChecked");
        });
      } 
    }
});

Кроме того, вы обычно не устанавливаете начальные значения, как в случае с isChecked = true; Я считаю, что это создает статическое общее свойство в прототипе (а не то, что вы намеревались). Вместо этого установите свойство при инициализации или передайте его из исходных данных json.

См. код: http://jsfiddle.net/JqZK2/5/

person Sam Selikoff    schedule 18.04.2014
comment
Буду, к сожалению пока не набрала очков. Я зарегистрировался недавно. Но если я наберу 15 баллов, я поддержу предыдущие полезные ответы. - person gsanta; 18.04.2014