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

Eri*_*off 2 javascript ember.js ember-data ember-cli ember-components

我正在使用带有ember-data 2.0的Ember 2.0.

在Rails中,使用真实的模型实例来模拟表单和组件是很常见的.对于posts/new表单,您将传入a 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>
Run Code Online (Sandbox Code Playgroud)

然后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"));
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

上面的示例确实有效,但需要this.store.createRecord.但据我所知,该组件无法访问该商店.这是理智的,因为那将是一个混乱全球国家的组成部分.此外,createRecord如果用户导航离开而不保存模型,则在使用时最终会在商店中存在大量残留模型.

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

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

Kub*_*iał 6

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

在您的示例中,您根本不必使用store组件.您可以Ember.Object在每个addCategory动作执行时创建一些实例,这些实例将发送给您的父级.此父级将获取数组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"));
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

在您的路线中,您可以执行以下操作:

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

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

{{category-form categories=categories saveCategories="saveCategories" addCategory="addCategory}}
Run Code Online (Sandbox Code Playgroud)

然后在你的路线/控制器中:

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