创建未附加到商店的 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
}
}
我正在使用 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
}
}