简体   繁体   English

Ember.js-列出商店中的值

[英]Ember.js - List values from store

From a route or component, I want to create an array of values from store data. 从路线或组件,我想从存储数据创建值数组。 Eg I have a project model and I want to get a list of project names i can use in select boxes, table headings... 例如,我有一个项目模型,我想获得一个项目名称列表,可以在选择框,表标题中使用...

I've tried the following and looked at computed properties, but can't get this working? 我尝试了以下内容,并查看了计算的属性,但无法正常工作吗?

// user route

model() {

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

    ...

Update: 更新:

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

It isn't working because you need to return a promise object from the model method of the route. 它不起作用,因为您需要从路由的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'));
}

I think the basics of what you need can be answered with the beforeModel() hook. 我认为可以使用beforeModel()挂钩来回答所需的基础知识。 The beforeModel() hook returns a promise, which will be fulfilled before the model() hook will be called. beforeModel()挂钩返回一个承诺,该承诺将在调用model()挂钩之前实现。 That lets you load the list of projects first. 这样一来,您可以首先加载项目列表。 The following code (untested) should get you there: 以下代码(未经测试)应该可以帮助您:

// 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({});
    }
  }
});

and your route, with some changes: 和您的路线,但有一些更改:

// 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...
  }
}

If you want to use the projects in your template, you can just use them like so: 如果要使用模板中的项目,则可以像这样使用它们:

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

and if you want the projectNames array available, remember to use setupController as you did in your question. 如果希望projectNames数组可用,请记住像在问题中一样使用setupController

In fact, in my experience you probably rarely want to use the projectNames array, but instead are better off iterating through the set of projects. 实际上,以我的经验,您可能很少希望使用projectNames数组,但是最好遍历项目集。 This is particularly true in templates. 在模板中尤其如此。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM