【问题标题】:Using set() on an array在数组上使用 set()
【发布时间】:2013-10-07 14:15:43
【问题描述】:

我有一个 EmberArray,可以缓存当天的所有活动。因此,如果我从服务器中提取了 7 月 1 日的活动,它将在 activitiesByDay['2013-07-01'] 中找到。我的问题是如何获取()和设置()这些数组项,以便我可以利用 Ember 的运行循环和数据绑定属性。

这是完整的代码:

module.exports = App.ActivitiesRoute = App.AuthenticatedRoute.extend({
    onDate: null,
    actionList: Ember.ArrayController.create(),
    activitiesByDate: Ember.Array,
    activitiesOnDate: function() {
        return this.get('activitiesByDate')[this.get('onDate')].content;
    }.property('activitiesByDate','onDate'),
    if (!this.get('activitiesByDate')[params.on_date]) {
        this.set('activities', this.store.find('activity', {on_date: params.on_date}));
        this.get('activitiesByDate')[params.on_date] =
            this.store.filter('activity',function(activity){        
                var itemDate = new Date(activity.get('start_time'));
                itemDate = moment(itemDate).format('YYYY-MM-DD');
                return itemDate === params.on_date;
            });
    }

如您所见,显示...的订单项

this.get('activitiesByDate')[params.on_date] =

是一个问题,因为我在不让 Ember 知道的情况下进行更改。问题是我找不到在数组上使用 Ember 的 set() 的方法,数组的键是“YYYY-MM-DD”格式的日期。我相信,这个关键结构要求我使用 Javascript 的括号表示法与 Ember 应该处理的点表示法。

---- 更新----

我稍微更新了ActivitiesRoute,使activitiesByDate 是一个对象而不是Ember.Array。我还将所有 setter/getter 更改为该对象的属性以使用 Embers get/set()`

App.ActivitiesRoute = App.AuthenticatedRoute.extend({
    onDate: null,
    activitiesByDate: Ember.Object.create(),
    activitiesOnDate: function() {
        return this.get('activitiesByDate.' + this.get('onDate'));
    }.property('activitiesByDate'),

    model: function(params) {
        this.set('onDate', params.on_date);
        // check if the given date has activities already loaded and if not then load it
        // if it does then do NOT reload. In the case of wanting a refresh use the refreshDate() method
        if (!this.get('activitiesByDate')[params.on_date]) {
            console.log('getting activities for: ' + params.on_date);
            this.set('activities', this.store.find('activity', {on_date: params.on_date})); // go get the dates from Server
            this.set('activitiesByDate.' + [params.on_date], this.store.filter('activity',function(activity){       
                var itemDate = new Date(activity.get('start_time'));
                itemDate = moment(itemDate).format('YYYY-MM-DD');
                return itemDate === params.on_date;
            }));
        }

        return true;
    },
    setupController: function(controller, model) {
        controller.set('activitiesByDate',this.get('activitiesByDate'));
    }

activitiesByDate 对象似乎工作正常。下面是一个例子,说明它在三个不同的日期之后的状态:

查看这些对象内部,我可以看到它们包含适量的活动,因此该部分看起来不错。不幸的是,我的计算属性——activitiesOnDate 在我在浏览器中点击重新加载时没有被更新。

【问题讨论】:

  • 你有没有试过在arraycontroller中设置新项目后手动调用this.get('activitiesByDate').enumerableContentDidChange()通知系统:github.com/emberjs/ember.js/tree/v1.0.0/packages/ember-runtime/…
  • 啊。我确实尝试“触摸”它以发出更新信号,但不知道 enumerableContentDidChange() 方法。让我再试一次。我认为这可能是一个非常可行的解决方案。
  • 好吧,我很茫然。仍然喜欢您的建议,但是当我尝试实施它时,它抱怨 activitiesByDate 没有 enumerableContentDidChange() 属性。然而,看看调试器,我可以清楚地看到它有 Enumerable mixin。

标签: ember.js


【解决方案1】:

如果你使用set('someProperty.' + dynamicProperty, value)get('someProperty.' + dynamicProperty),你会得到你想要的。在你的情况下:

获取过滤结果

//Instead of
this.get('activitiesByDate')[this.get('onDate')]

// You would use 
this.get('activitiesByDate.' + this.get('onDate'));

设置过滤结果

// Instead of
var filtered = this.store.filter('activity',function(activity){        
    var itemDate = new Date(activity.get('start_time'));
    itemDate = moment(itemDate).format('YYYY-MM-DD');
    return itemDate === params.on_date;
});

this.get('activitiesByDate')[params.on_date] = filtered;


// You would use 
var filtered = this.store.filter('activity',function(activity){        
    var itemDate = new Date(activity.get('start_time'));
    itemDate = moment(itemDate).format('YYYY-MM-DD');
    return itemDate === params.on_date;
});

// if some key change, notify the entire property
Ember.propertyWillChange(this, 'activitiesByDate');
this.set('activitiesByDate.' + params.on_date, filtered);
Ember.propertyDidChange(this, 'activitiesByDate');

【讨论】:

  • 好的,让我检查一下。我的印象是“2013-09-25”的数组下标无法通过点表示法引用,只有 [] 下标,我尝试了使用该语法的建议,但无济于事。
  • 我认为您的数据结构是一个对象,其中键是日期,值是像 (DS.FilteredRecordArray) 这样的数组。例如:{ '2013-05-05': [{ id: 1, ...}, ...] }。对吗?
  • activitiesByDate 是一个 Ember.Array。顺便说一句,我在调试控制台上尝试了你的解决方案,它似乎确实有效,但是我仍然没有得到我在实际代码执行中所期望的结果。需要再深入研究一下。
  • 我认为使用对象更容易,就像你所说的使用array[someThing] = value,只适用于索引。如果要使用字符串设置和获取数据,则需要使用纯 js 对象。要小心,因为这里 activitiesByDate: Ember.Array 您将 activitiesByDate 设置为 Ember.Array 类,这不是数组的新实例...
  • 问题是您的计算属性依赖于activitiesByDate,但当前更改的值是例如activitiesByDate.2012-05-01。当发生变化时,您需要手动通知activitiesByDate 属性。看看更新的答案。并在这个小提琴中看到一个简约的样本jsfiddle.net/marciojunior/urT3X
猜你喜欢
  • 2015-09-20
  • 1970-01-01
  • 2021-12-06
  • 1970-01-01
  • 2015-04-03
  • 1970-01-01
  • 1970-01-01
  • 2018-09-24
  • 1970-01-01
相关资源
最近更新 更多