Ember.js - 列出商店的价值

时间:2016-06-11 10:58:28

标签: javascript ember.js

从路径或组件中,我想从商店数据创建一个值数组。例如。我有一个项目模型,我想获得一个项目名称列表,我可以在选择框,表格标题中使用...

我已经尝试了以下内容并查看了计算属性,但无法使其正常工作?

// user route

model() {

    let projects = this.store.findAll('project').then((projects) => {
        return projects.mapBy('name');
    });

    ...

更新

// users.new route
import Ember from 'ember';

export
default Ember.Route.extend({

    projectNames: [],

    afterModel: function () {
        this._super(...arguments);
        return this.store.findAll('project').then((projects) => {
            this.set('projectNames', projects.mapBy('name'));
        });
    },

    setupController: function (controller) {
        this._super(...arguments);
        controller.set('projectNames', this.get('projectNames'));
    },

    model() {
        let user = this.store.createRecord('user'),
            projectRoles = [],
            projects = this.get('projectNames');

            console.log('projectNames: ' + this.get('projectNames'));

        projects.forEach((project) => {
            let projectRole = this.store.createRecord('projectRole', {
                project: project,
                role: 'Viewer'
            });
            projectRoles.push(projectRole);
        });

        // Create 1 role per project
        Ember.RSVP.all(projectRoles.map(projectRole => projectRole.save())).then((projectRoles) => {
            user.set('projectRoles', projectRoles);
        });

        return user;
    }
}

2 个答案:

答案 0 :(得分:3)

它不起作用,因为您需要从路径的model方法返回一个promise对象。

// return a promise object from the model.
// This is available as the `model` property in the route's controller
model() {
  return this.store.findAll('project')
},

// Store the list of names in a property ('projectNames') on the route's
// controller.
setupController(controller, models) {
  controller.set('projectNames', models.mapBy('name'));
}

答案 1 :(得分:2)

我认为您需要的基础知识可以通过beforeModel()钩子来回答。 beforeModel()挂钩返回一个promise,它将在调用model()挂钩之前完成。这允许您首先加载项目列表。以下代码(未经测试)可以帮助您:

// services/project-core.js
import Ember from 'ember';

export default Ember.Service.extend({
  store: Ember.inject.service(),
  projects: null,

  init() {
    this.set('projects', []);
  },

  // getProjects() needs to be called at least once before the projects are available in the application. Ideally this method will be called in the route's beforeModel() hook.
  getProjects() {
    if (this.get('projects').length === 0 {
      // this makes sure we only query for the projects once; you may not want this block. I personally like to avoid unneeded queries.
      return this.get('store').findAll('project').then(projects => {
        this.set('projects', projects);
      });
    } else {
      return Ember.RSVP.hash({});
    }
  }
});

和你的路线,有一些变化:

// users.new route
import Ember from 'ember';

export default Ember.Route.extend({
  projectCore: Ember.inject.service(),

  beforeModel() {
    return this.get('projectCore').getProjects();
  },

  model() {

    // Here you'll be able to do things like:
    this.set('projectNames', this.store.peekAll('project').map(function(x) {return x.get('name')}));

    // and from your code:
    let user = this.store.createRecord('user'),
        projectRoles = [],
        projects = this.get('projectNames');

    console.log('projectNames: ' + this.get('projectNames'));

    projects.forEach((project) => {
      let projectRole = this.store.createRecord('projectRole', {
          project: project,
          role: 'Viewer'
      });
      projectRoles.push(projectRole);
    });

    // and so on...
  }
}

如果您想在模板中使用这些项目,您可以像这样使用它们:

<ul>
  {{#each projectCore.projects as |project|}}
    <li>{{project.name}}</li>
  {{/each}}
</ul>

如果您希望projectNames数组可用,请记得像在问题中一样使用setupController

事实上,根据我的经验,您可能很少想使用projectNames数组,但最好是迭代一组项目。在模板中尤其如此。