创建未附加到商店的 Ember 个模型的实例

Creating instances of Ember models not attached to a store

我正在使用 Ember 2.0 和 ember-data 2.0。

在 Rails 中,使用模型的真实实例对表单和组件进行建模非常普遍。对于 posts/new 表单,您将传入 Post.new 并在 form.html.erb 模板中使用它。

在 Ember 中,这变得很困难,因为调用 new Post 会创建一个损坏的模型。相反,我们鼓励您使用商店,并使用 this.store.createRecord('post');.

这很好,但在构建独立组件时就不行了。例如,用户可以添加多个模型的表单,比如类别创建者。在我看来,结构如下:

category-form/template.hbs

<button {{action 'addCategory'}}>Add category</button>
{{#each categories as |category|}}
    {{input value=category.name}}
{{/each}}
<button {{action 'save'}}>Save</button>

那么 component.js 会是这样的:

category-form/component.js

import Ember from 'ember';
import Category from 'app/category/model';

export default Ember.Component.extend({
    categories: [],

    actions: {
        addCategory() {
            // THIS DOES NOT WORK
            this.get("categories").pushObject(new Category);
        },

        save() {
            this.sendAction("saveCategories", this.get("categories"));
        }
    }
});

上面的示例确实有效,但需要 this.store.createRecord。但据我所知,该组件无权访问商店。这是理智的,因为那将是扰乱全局状态的组件。此外,在使用 createRecord 时,如果用户在未保存模型的情况下导航离开,您最终会在商店中获得大量残差模型。

我希望此示例中的 category-form 组件与全局状态的其余部分完全隔离。

我的问题是,如何使用 ember 逻辑正确处理?

您写的所有内容都是正确的,它被认为是一个很好的模式 - 您的组件在没有存储的情况下工作,其中一些 parent(最好是路由,但可能是控制器)正在处理将这些数据持久化到 API.

在您的示例中,您根本不必在组件中使用 store。您可以在每个 addCategory 操作执行时创建一些 Ember.Object 实例,这些实例将发送到您的 parent。这个parent会得到Ember.Object的数组,将你要使用的属性复制到模型实例中保存。

import Ember from 'ember';

export default Ember.Component.extend({
    categories: [],

    actions: {
        addCategory() {
            this.get("categories").pushObject(Ember.Object.create({
                name: ''
            });
        },

        save() {
            this.sendAction("saveCategories", this.get("categories"));
        }
    }
});

并且在你的路线中你可以进行如下操作:

actions: {
  saveCategories(categories) {
    let categoryRecords = categories.map((item) => {
      return this.store.createRecord('category', { name: item.get('name') });
    });
  }
}

另一方面,如果您需要 Ember 数据模型的某些功能作为关系,您实际上可以将操作 addCategory 发送到 route/controller,创建模型并作为对该组件的绑定向下传递:

{{category-form categories=categories saveCategories="saveCategories" addCategory="addCategory}}

然后在你的 route/controller:

   categories: [], 
   actions: {
      addCategory() {
        this.get('categories').pushObject(this.store.createRecord('category'));
      },
      saveCategories() {
        this.get('categories')... // do what you want with them
      }
    }