Arrays 重新排序用于创建子视图的数组后,Ember视图未更新

Arrays 重新排序用于创建子视图的数组后,Ember视图未更新,arrays,sorting,ember.js,Arrays,Sorting,Ember.js,我有一个活动视图,其中包含一系列活动。此数组有时会根据用户可以更新的计算属性(与家庭的距离)进行排序。当数组排序后,我希望子视图按照新的顺序重新渲染。以下是我的模板和视图: index.html 当我更改distance_to_home属性时,console.log输出显示列表数组已正确排序,但子视图不会按新顺序重新渲染。如果我离开此视图,然后返回(再次渲染),则会显示正确的顺序 我应该如何使视图自动更新 谢谢 编辑 这似乎正在工作,我的“活动”计算函数肯定正在启动,但没有对视图进行重新排序。。

我有一个活动视图,其中包含一系列活动。此数组有时会根据用户可以更新的计算属性(与家庭的距离)进行排序。当数组排序后,我希望子视图按照新的顺序重新渲染。以下是我的模板和视图:

index.html

当我更改distance_to_home属性时,console.log输出显示列表数组已正确排序,但子视图不会按新顺序重新渲染。如果我离开此视图,然后返回(再次渲染),则会显示正确的顺序

我应该如何使视图自动更新

谢谢

编辑 这似乎正在工作,我的“活动”计算函数肯定正在启动,但没有对视图进行重新排序。。。我也试着使用一个观察者,但结果是一样的

  App.ActivitiesView = Em.View.extend({
    templateName: 'activities',
    classNames: ['activities rounded shadow'],
    homeBinding: 'App.user.home',
    activities: [],
    homeChanged: (function() {
      console.log("homeChanged()");
      this.set('activities', App.activityController.activities.sort(this.compare_activities));
      return null;
    }).observes('home'),

    compare_activities: function(a, b) {
      var result;
      result = 0;
      if (App.user.home != null) {
        result = a.get('distance_to_home') - b.get('distance_to_home');
      }
      return result;
    },

  });
我还尝试将“activities”参数设置为空数组,然后将其重置为有序数组以强制其重新渲染,但这没有效果

  App.ActivitiesView = Em.View.extend({
    templateName: 'activities',
    classNames: ['activities rounded shadow'],
    homeBinding: 'App.user.home',
    activities: [],
    homeChanged: (function() {
      console.log("homeChanged()");
      this.set('activities', []);
      this.set('activities', App.activityController.activities.sort(this.compare_activities));
      return null;
    }).observes('home'),

    compare_activities: function(a, b) {
      var result;
      result = 0;
      if (App.user.home != null) {
        result = a.get('distance_to_home') - b.get('distance_to_home');
      }
      return result;
    },

  });
编辑(第二) 看来使用Ember.copy最终解决了这个问题。将数组属性设置为空数组(或null)没有任何效果。以下是最终有效的视图代码:

  App.ActivitiesView = Em.View.extend({
    templateName: 'activities',
    classNames: ['activities rounded shadow'],
    homeBinding: 'App.user.home',
    activities: [],
    homeChanged: (function() {
      var list;
      list = App.activityController.activities.sort(this.compare_activities);
      this.set('activities', Ember.copy(list), true);
      return null;
    }).observes('home'),
    compare_activities: function(a, b) {
      var result;
      result = 0;
      if (App.user.home != null) {
        result = a.get('distance_to_home') - b.get('distance_to_home');
      }
      return result;
    }
  });
这有用吗

把这个简单的例子放在一起,我有点困惑,为什么在ArrayController中对内容数组进行排序时视图更新不能“正常工作”。似乎有两件简单的事情可以触发视图更新。要么:

  • 将内容数组设置为null,对原始内容进行排序,然后设置排序后的内容

  • 排序时通过Ember.copy()克隆内容数组
我猜Ember会检测到何时设置了一个全新的数组对象,并触发所有预期的绑定/视图更新。否则,它可能正在进行某种缓存,如果数组对象没有更改(即,它已就地排序),则不会触发绑定?只是猜测而已

更新:
请参阅讨论@,它使用propertyWillChange()和PropertyIDChange()改进了解决方法(http://jsfiddle.net/rNzcy/4/)--应该比克隆一个大数组更有效。

我遇到了同样的问题。而且我不认为观察
数组。@each
数组。length
都是好的做法。最后我找到了这个,即调用
this.propertyDidChange('foo')

我注意到您使用了一个数组控制器。我的控制器是一个标准的余烬对象。我会很快尝试你发布的内容,然后回来。亚当,是“Ember.copy()”起了作用。再次感谢您的时间和努力(示例代码非常有用)很酷,很高兴这对您有所帮助。注意,我之所以使用ArrayController是因为它是“绑定感知”的,请参阅,但这就是为什么我们不得不使用Ember.copy()(或我提到的其他解决方法)的原因。我可能是余烬中的一只虫子?我将在github上分享这个示例,看看开发人员怎么说。您能提供一个带有示例数据的JSFIDLE吗?我认为
Ember.copy
不是最好的解决方案。还可以查看最近推出的
arrangedContent
[
  App.ActivitiesView = Em.View.extend({
    templateName: 'activities',
    classNames: ['activities rounded shadow'],
    homeBinding: 'App.user.home',
    activities: [],
    homeChanged: (function() {
      console.log("homeChanged()");
      this.set('activities', []);
      this.set('activities', App.activityController.activities.sort(this.compare_activities));
      return null;
    }).observes('home'),

    compare_activities: function(a, b) {
      var result;
      result = 0;
      if (App.user.home != null) {
        result = a.get('distance_to_home') - b.get('distance_to_home');
      }
      return result;
    },

  });
  App.ActivitiesView = Em.View.extend({
    templateName: 'activities',
    classNames: ['activities rounded shadow'],
    homeBinding: 'App.user.home',
    activities: [],
    homeChanged: (function() {
      var list;
      list = App.activityController.activities.sort(this.compare_activities);
      this.set('activities', Ember.copy(list), true);
      return null;
    }).observes('home'),
    compare_activities: function(a, b) {
      var result;
      result = 0;
      if (App.user.home != null) {
        result = a.get('distance_to_home') - b.get('distance_to_home');
      }
      return result;
    }
  });