Вычисляемое свойство выдает ошибку при инициализации

(ссылка http://jsfiddle.net/kapLv0mt/4/)

У меня есть

Member = Ractive.extend({
  template : "<div>{{name}}</div>",
  computed : {male : function(){this.get('gender')=='m'}}
})

ff = new Ractive({
  el : '#container',
  template : "there are {{male_count}} males{{#family}}<member/>{{/family}}",
  components : {member : Member},
  data : {family : [
      {name:'Fred',gender:'m'},
      {name:'Wilma',gender:'f'},
      {name:'Rocky',gender: 'm'},
      {name:'Bubbles',gender: '?'}
  ]},
  computed : { male_count : function(){
    return _(this.findAllComponents('member')).filter(function(mem){return mem.get('male')}).length;
   }
  }
})

Во время инициализации ractive возникает ошибка, а также вычисляемое свойство «male_count» не возвращает правильное значение. Ошибка инициализации возникает из-за того, что свойство включено в шаблон, но даже в этом случае вычисляемое свойство не возвращает правильное значение, возможно, потому, что оно было неправильно вычислено при инициализации.

Как я могу инициализировать атрибут объекта Ractive, который зависит от компонентов?

Изменить: по предложению ответчика я упомяну здесь, что пример кода очень сильно упрощен по сравнению с моим фактическим кодом. Алгоритм фильтрации компонентов в фактическом коде основан примерно на 9 критериях сравнения, включая даты, совпадения текста, числовые диапазоны, где пороговые значения вводятся через пользовательский интерфейс для фильтра списка. По этой причине я хотел бы придерживаться идеи (как в примере) реализации теста фильтра в компоненте.


person Les Nightingill    schedule 15.09.2015    source источник


Ответы (1)


Во-первых, вам даже не нужно запрашивать компонент member для подсчета мужчин в данных. Данные уже находятся в родительском компоненте, вычисленные также находятся в родительском компоненте. Почему бы просто не спросить себя?

computed: {
    male_count: function () {
        return this.get('family').filter(function (familyMember) {
            return familyMember.gender === 'm'
        }).length;
    }
}

Также полезно помнить, что в Ractive вы работаете с данными, а не с DOM (или, в данном случае, с компонентами). Как только вы начнете использовать операции DOM или находить компоненты, ваш дизайн потребует некоторого переосмысления.

person Joseph    schedule 16.09.2015
comment
Спасибо, @Джозеф Мечтатель. Да, это будет работать для простого случая. Я упростил свою проблему для SO. Наверное, слишком много. На самом деле у меня есть сложный алгоритм динамического сопоставления с несколькими атрибутами в фильтре (даты, числовые диапазоны, текстовые совпадения и т. д.). По этой причине мне нужно, чтобы компонент владел алгоритмом фильтрации, как в моем коде выше, иначе код становится сложнее рассуждать. - person Les Nightingill; 16.09.2015
comment
Я думал о вашем комментарии по дизайну, @JtD. Компонент — это фрагмент DOM, связанный с подмножеством данных страницы. Он может/должен иметь свое собственное поведение. Для меня совершенно логично, что он должен включать себя (или нет) в DOM на основе критериев, применяемых к связанным с ним данным, а не делегировать это решение родителю. Экземпляры Root Ractive стали бы громоздкими, если бы они управляли всей страницей. - person Les Nightingill; 16.09.2015
comment
@LesNightingill Ну да. Будут времена, когда инкапсуляция функциональности в компоненте будет иметь смысл. Но в контексте этого примера (в котором должны быть ответы SO) это просто ненужный круговой путь. Возможно, стоит упомянуть в посте сложность, которая требует компонента для включения этой логики. - person Joseph; 16.09.2015