Вы дважды изменили *** в одном рендере

После обновления до 1.13 я получаю это исключение, и я не могу понять, в чем проблема. Я также не мог найти полезный ресурс, который решает мою проблему.

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

Я создал пример jsbin: http://emberjs.jsbin.com/roderameya/edit?html,js,console,output

UPDATE

В соответствии с запросом я размещаю некоторый код, который ближе к моей реальной реализации.

Ember.Controller.extend({

  filter: '',

  resultCount: {
    total: 0,
    matches: 0,
    mismatches: 0
  },

  results: function() {
    var items = this.get('model'),
        matches = [],
        resultCount = {};

    // Apply search filter
    matches = items.filter(function(item){
      // Just a dummy filter function
      return true;
    });

    // We need the total number matched by the filter string
    resultCount.total = matches.length;

    // The already matched items must be narrowed further down
    matches = matches.filter(function(item) {
      // Another filter function
      return true;
    });

    resultCount.matches = matches.length;
    resultCount.mismatches = resultCount.total - matches.length;

    this.set('resultCount', resultCount);

    return matches;

  }.property('model', 'filter'),

});

Ответ 1

Попробуйте, чтобы ваши свойства не задавали другие свойства, а зависели друг от друга:

App.IndexController = Ember.Controller.extend({
  count: function() {
    return this.get("data.length") || 0;
  }.property('data.length'),

  data: [1,2,3]
});

Обновлен jsbin для вас.

UPDATE

В основном, ваш resultCount - это временная переменная, от которой мы можем избавиться, а остальные просто объединяют вычисляемые свойства:

обновленный jsbin для расширенного примера

код:

// Index controller
App.IndexController = Ember.Controller.extend({
  count: Ember.computed('filteredItems.length', function(){
    return this.get('filteredItems.length');
  }),

  data: [
    Ember.Object.create({ name: "jim", age: 15 }),
    Ember.Object.create({ name: "jeff", age: 42 }),
    Ember.Object.create({ name: "eric", age: 7 })
  ],

  filter: RegExp(".*"),
  ageFilter: -1,

  mismatchCount: Ember.computed('filteredItems.length', 'secondPassFilteredItems.length', function() {
    return this.get('filteredItems.length') - this.get('secondPassFilteredItems.length');
  }),

  filteredItems: Ember.computed('data', 'filter', function() {
    var controller = this;
    return this.get('data').filter(function(item) {
      return item.get('name').match(controller.get("filter"));
    });
  }),

  secondPassFilteredItems: Ember.computed('filteredItems', 'ageFilter', function() {
    var controller = this;
    var ageFilter = controller.get("ageFilter");
    if (Ember.isEqual(ageFilter, -1)) {
      return this.get('filteredItems');
    } else {

      return this.get('filteredItems').filter(function(item) {
        // more filtering
        return item.get("age") <= ageFilter;
      });
    }
  }),

  results: Ember.computed.alias('secondPassFilteredItems'),

  actions: {
    filterByJ: function() {
      this.set('filter', new RegExp("j"));
    },
    filterByEric: function() {
      this.set('filter', new RegExp("eric"));
    },
    filterAllNames: function() {
      this.set('filter', new RegExp(".*"));
    },
    filterYoungins: function() {
      this.set('ageFilter', 15);
    },
    filterAllAges: function() {
      this.set('ageFilter', -1);
    }
  }

});

Использование шаблона:

<script type="text/x-handlebars" data-template-name="index">
    <p>Results found: {{count}}</p>
    <p>Diff between first and second filter: {{mismatchCount}}</p>
    <p>First Filter:
      <button {{action 'filterAllNames'}}>all people</button>
      <button {{action 'filterByJ'}}>People with J in name</button>
      <button {{action 'filterByEric'}}>People named 'eric'</button>
    </p>
    <p> Second Filter:
      <button {{action 'filterAllAges'}}>all ages</button>
      <button {{action 'filterYoungins'}}>15 years old or younger</button>
    </p>
    <ul>
    {{#each results as |item|}}
      <li>{{item.name}} is {{item.age}} years old</li>
    {{/each}}
    </ul>
  </script>