后使用重新排序阵列创建子视图灰烬视图未更新 [英] Ember view is not updating after re-ordering array used to create child views

查看:133
本文介绍了后使用重新排序阵列创建子视图灰烬视图未更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含一系列活动的活动视图。这个阵列被基于计算属性(distanced_from_home),该用户可以更新有时排序。当该阵列被排序欲子视图被通过根据新的顺序重新呈现。这是我的模板,然后查看:

index.html的

 <脚本类型=文/ X-车把数据模板的名称=活动>
    < H1>活动< / H1>
    {{#each活动}}
      {{查看App.ActivityView activityBinding =此}}
    {{/每}}
  < / SCRIPT>

app.js

  App.ActivitiesView = Em.View.extend({
    TEMPLATENAME:'活动',
    活动:(函数(){
      VAR清单;
      名单= App.activityController.activities;
      的console.log(活动视图);
      的console.log(名单);
      返回列表;
    })。酒店('App.activityController.activities','App.activityController.activities。@ each.distance_to_home')。缓存()
  });

当我使distance_to_home属性发生变化时,输出的console.log显示列表数组排序正确,但在新的秩序孩子们的意见不重新呈现。如果我离开这个观点再复出吧(它再次渲染),然后按照正确的顺序显示。

我应该怎么做才能视图自动更新?

谢谢,

修改

这似乎是工作<一个href=\"http://stackoverflow.com/questions/8962839/sorting-a-list-in-emberjs-and-having-that-reflect-in-the-view\">here和我的'活动'计算函数肯定是射击,但鉴于没有重新排序...我还试图用一个观察者,但结果是一样的。

  App.ActivitiesView = Em.View.extend({
    TEMPLATENAME:'活动',
    类名:['活动四舍五入影子'],
    homeBinding:App.user.home',
    活动:[],
    homeChanged:(函数(){
      的console.log(homeChanged());
      this.set('活动',App.activityController.activities.sort(this.compare_activities));
      返回null;
    })。观察(家),    compare_activities:功能(A,B){
      VAR的结果;
      结果= 0;
      如果(App.user.home!= NULL){
        结果= a.get('distance_to_home') - b.get('distance_to_home');
      }
      返回结果;
    },  });

我也尝试了活动参数设置为空数组,然后将其恢复到有序阵列,迫使它重新渲染,但这没有影响。

  App.ActivitiesView = Em.View.extend({
    TEMPLATENAME:'活动',
    类名:['活动四舍五入影子'],
    homeBinding:App.user.home',
    活动:[],
    homeChanged:(函数(){
      的console.log(homeChanged());
      this.set('活动',[]);
      this.set('活动',App.activityController.activities.sort(this.compare_activities));
      返回null;
    })。观察(家),    compare_activities:功能(A,B){
      VAR的结果;
      结果= 0;
      如果(App.user.home!= NULL){
        结果= a.get('distance_to_home') - b.get('distance_to_home');
      }
      返回结果;
    },  });

编辑(二)

如此看来,使用Ember.copy终于解决了这一点。数组属性设置为一个空数组(或空)没有任何影响。这里的查看code,它终于摸索:

  App.ActivitiesView = Em.View.extend({
    TEMPLATENAME:'活动',
    类名:['活动四舍五入影子'],
    homeBinding:App.user.home',
    活动:[],
    homeChanged:(函数(){
      VAR清单;
      清单= App.activityController.activities.sort(this.compare_activities);
      this.set('活动',Ember.copy(列表),TRUE);
      返回null;
    })。观察(家),
    compare_activities:功能(A,B){
      VAR的结果;
      结果= 0;
      如果(App.user.home!= NULL){
        结果= a.get('distance_to_home') - b.get('distance_to_home');
      }
      返回结果;
    }
  });


解决方案

这是否帮助? http://jsfiddle.net/rNzcy/

放在一起这个简单的例子,我是一个有点困惑,为什么视图更新不只是工作排序中ArrayController内容阵列时。它似乎有2个简单的事情可以做,以触发视图更新。或者:


  • 将内容数组为null,排序的原始内容,然后将所排序的内容。


  • 排序它的时候,通过Ember.copy克隆的内容数组()

我想,当一个完全新的Array对象设置灰烬检测,并触发所有预期绑定/视图更新。否则,也许它做一些缓存,如果Array对象不改变(即它的地方排序)则没有绑定火?只是猜测。

更新:
见讨论@ <一个href=\"https://github.com/emberjs/ember.js/issues/575#issuecomment-4397658\">https://github.com/emberjs/ember.js/issues/575#issuecomment-4397658其中有利用propertyWillChange()和propertyDidChange()改进的解决方法(http://jsfiddle.net/rNzcy/4/) - 应该是很多更有效的再克隆一个大阵

I have an activities view that contains an array of activities. This array gets sorted sometimes based on a calculated property(distanced_from_home) that the user can update. When the array is sorted I want the child views to be re-rendered by according to the new order. Here is my Template and View:

index.html

  <script type="text/x-handlebars" data-template-name="activities">
    <h1>Activities</h1>
    {{#each activities}}
      {{view App.ActivityView activityBinding="this"}}
    {{/each}}
  </script>

app.js

  App.ActivitiesView = Em.View.extend({
    templateName: 'activities',
    activities: (function() {
      var list;
      list = App.activityController.activities;
      console.log("Activities View");
      console.log(list);
      return list;
    }).property('App.activityController.activities', 'App.activityController.activities.@each.distance_to_home').cacheable()
  });

When I cause the distance_to_home property to change, the console.log output shows the list array is properly sorted, but the children views are not re-rendered in the new order. If I leave this view and then comeback to it (it is rendered again) then the correct order is shown.

What should I do to get the view to update automatically?

Thanks,

EDIT

This seems to be working here and my 'activities' computed function is definitely firing, but no re-ordering of the view... I also tried to use an observer, but the results are the same.

  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;
    },

  });

I also tried to set the 'activities' parameter to an empty array and then reset it to the ordered array to force it to re-render, but this has no effect.

  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;
    },

  });

EDIT (the second)

So it seems that using Ember.copy finally solved this. Setting the array property to an empty array (or null) did not have any effect. Here's the View code that finally worked:

  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;
    }
  });

解决方案

Does this help? http://jsfiddle.net/rNzcy/

Putting together this simple example, I was a little confused why the view update didn't "just work" when sorting the content array in the ArrayController. It seems there are 2 simple things you can do to trigger the view update. Either:

  • Set the content array to null, sort the original content, and then set the sorted content.

or

  • Clone the content array when sorting it, via Ember.copy()

I guess Ember detects when a completely new Array object is set, and that triggers all the expected binding/view updates. Otherwise, maybe it's doing some sort of caching and if the Array object does not change (i.e. it's sorted in place) then no bindings fire? Just guessing.

UPDATE: See discussion @ https://github.com/emberjs/ember.js/issues/575#issuecomment-4397658 which has an improved workaround using propertyWillChange() and propertyDidChange() (http://jsfiddle.net/rNzcy/4/) -- should be a lot more efficient then cloning a large array.

这篇关于后使用重新排序阵列创建子视图灰烬视图未更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆