从Ember计算属性返回一个数组

时间:2014-05-01 17:35:59

标签: arrays ember.js promise

我有两个相关的模型 - 任务和要求。要求可以是3种类型之一(零件,工具,材料)。任务可以有多个要求,包括几个相同的类型。

Task A
    Requirement 1 (Part)
    Requirement 2 (Part)
    Requirement 3 (Tool)
    Requirement 4 (Material)
    Requirement 5 (Tool)

查看单个任务时,我想在一种摘要视图中按类型对需求列表进行分组。

Task A
    Parts Requirements (2)
    Tooling Requirements (2)
    Materials Requirements (1)

我的一个computedProperty主要在我的TaskController中运行,但我似乎无法让它返回我构建的需求摘要数组。所有夹具数据都适用于两个模型(我可以迭代每个需求并在模板中显示它没有问题)。

以下是模型

任务模型

App.Task = DS.Model.extend({
    name: DS.attr()
    requirements: DS.hasMany('requirement', { async: true})
});

需求模型

App.Requirement = DS.Model.extend({
    task_id: DS.belongsTo('task'),
    type: DS.attr(),
    description: DS.attr(),
    quantity: DS.attr()
})

这是控制器:

App.TaskController

App.TaskController = Em.ObjectController.extend({
    requirementSummary: function () {
        var self = this,
            results = [];

        self.get('requirements').then(function(requirements) {

            var arrRequirements = requirements.get('content');

            var parts = {
                name: 'Parts',
                description: '',
                count: 0,
                css_class: 'fa-cog'
            },

            tools = {
                name: 'Tools',
                description: '',
                count: 0,
                css_class: 'fa-wrench'
            },

            materials = {
                name: 'Materials',
                description: '',
                count: 0,
                css_class: 'fa-tint'
            };

            arrRequirements.forEach(function (requirement) {
                if (requirement._data.name == 'Part') {
                    parts.description += requirement._data.description + ' (' + requirement._data.quantity + ')<br>';
                    parts.count++;
                } else if (requirement._data.name == 'Material') {
                    materials.description += requirement._data.description + ' (' + requirement._data.quantity + ')<br>';
                    materials.count++;
                } else if (requirement._data.name == 'Tooling') {
                    tools.description += requirement._data.description + ' (' + requirement._data.quantity + ')<br>';
                    tools.count++;
                }
            });

            if (parts.description !== '') {
                parts.description = parts.description.replace(/(<br>\s*)+$/);
            } else {
                parts.description = "No Parts requirements found";
            }

            if (materials.description !== '') {
                materials.description = materials.description.replace(/(<br>\s*)+$/);
            } else {
                materials.description = "No Materials requirements found";
            }

            if (tools.description !== '') {
                tools.description = tools.description.replace(/(<br>\s*)+$/);
            } else {
                tools.description = "No Tooling requirements found";
            }

            results.pushObject(parts);
            results.pushObject(tools);
            results.pushObject(materials);
        });

        return results;

    }.property()
});

目前它返回空结果数组,因为它正在等待self.get承诺完成。如果我返回self.get('requirements').then(...)的结果,那么它返回promise,而不是结果数组,而Ember并不高兴,因为它不是数组。我想要的是它返回填充的结果数组。

我发现的最接近的问题是here,但它要么没有解决问题,要么我错过了什么。

2 个答案:

答案 0 :(得分:0)

您需要使用requirementSummary使用可观察的模式,或者在完成解析之后使用 var arrRequirements = requirements.get('content');

此外,由于需求已经是可迭代字段,因此不需要这样做:

  requirement.get('description')

你应该使用getter获取一个属性,而不是去._data.property

task

将此添加到您的{{#each requirement in requirementSummary}} Name: {{requirement.name}} - Total: {{requirement.total}} {{/each}} 模板,您应该看到它填充(异步):

{{1}}

答案 1 :(得分:0)

所有路线似乎都与灯具一样有效 - 我可以使用{{#each requirement in requirements}}并列出每个单独的要求而没有任何问题。只是遇到生成汇总属性并在计算完毕后访问它的问题。

来自routes / application_routes.js 的

this.resource( 'tasks', function () {
    this.resource( 'task', { path: ':task_id' }, function () {
       this.resource( 'task_requirements', { path: 'requirements' } );
    } );
} );
来自routes / task_routes.js

// List Tasks
App.TasksRoute = Em.Route.extend({
    model: function () {
        return this.store.find('task');
    }
});

// Task Detail Route
App.TaskRoute = Em.Route.extend({
    model: function(params) {
        return this.store.find('task', params.task_id);
    }
});

// Task Requirements Route
App.TaskRequirementsRoute = Em.Route.extend({
    beforeModel: function () {
        this.set('task', this.modelFor('task'));
    }
});

赛程

// SAMPLE TASK FIXTURE.
App.Task.FIXTURES = [
    {
        "id": 1,
        "name": "Test Task #1",
        "description": "This is a test task. There are many like it but this one is mine.",
        "requirements": [ 1, 2, 3, 4 ]
    }
];

// SAMPLE REQUIREMENT FIXTURE
App.Requirement.FIXTURES = [
    {
        "id": 1,
        "task_id": 1,
        "type": "Part",
        "description": "This is a Part requirement",
        "quantity": 4
    },
    {
        "id": 2,
        "task_id": 1,
        "type": "Part",
        "description": "This is a Part requirement",
        "quantity": 1
    },
    {
        "id": 3,
        "task_id": 1,
        "type": "Material",
        "description": "This is a Material requirement",
        "quantity": 3
    },
    {
        "id": 4,
        "task_id": 1,
        "type": "Tool",
        "description": "This is a Tooling requirement",
        "quantity": 1
    }
];