您在单个渲染中修改了两次***

时间:2015-07-16 18:00:09

标签: ember.js

升级到1.13后,我得到了这个例外,我无法弄清楚是什么问题。我也找不到任何有用的资源来解决我的问题。

我在另一个计算属性中设置的属性会发生这种情况。但这个属性肯定只被调用一次。

我创建了一个jsbin示例:http://emberjs.jsbin.com/roderameya/edit?html,js,console,output

更新

根据要求,我发布了一些更接近我真实实现的代码。

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 个答案:

答案 0 :(得分:7)

尝试让您的属性不设置其他属性,而是相互依赖:

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

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

Updated jsbin for you

<强> 更新

基本上,你的resultCount是一个我们可以摆脱的临时变量,其余的只是将计算属性链接在一起:

updated jsbin for advanced example

代码:

// 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>