Ember.js 余烬数据2-以一种形式提交两个相关模型
总余烬新手在这里。我的后端是用Rails编写的。这一部分很好,所以假设服务器端一切正常。具体情况如下: 我有两种型号 项目(包含许多项目详细信息) 项目详细信息(属于项目) 我已经确认:Ember.js 余烬数据2-以一种形式提交两个相关模型,ember.js,ember-data,Ember.js,Ember Data,总余烬新手在这里。我的后端是用Rails编写的。这一部分很好,所以假设服务器端一切正常。具体情况如下: 我有两种型号 项目(包含许多项目详细信息) 项目详细信息(属于项目) 我已经确认: 我可以从我的projects/new.hbs模板创建一个新项目 我的索引路由检索所有项目以及与它们关联的项目详细信息 “我的显示路线”检索单个项目及其关联的项目详细信息 我想做的是,从我的projects/new.hbs模板提交一个项目模型和一个项目详细信息模型 我知道new.hbs中的表单应该在一个组件中,但
export default DS.Model.extend({
project_details: DS.hasMany('project_detail', { async: true }),
project_name: DS.attr('string'),
status: DS.attr('string')
});
export default DS.Model.extend({
project: DS.belongsTo('project', { async: true }),
project_id: DS.attr('number'),
feature_name: DS.attr('string'),
hours_billed: DS.attr('number'),
available_hours: DS.attr('number'),
amout: DS.attr('number')
});
项目详细信息模型
export default DS.Model.extend({
project_details: DS.hasMany('project_detail', { async: true }),
project_name: DS.attr('string'),
status: DS.attr('string')
});
export default DS.Model.extend({
project: DS.belongsTo('project', { async: true }),
project_id: DS.attr('number'),
feature_name: DS.attr('string'),
hours_billed: DS.attr('number'),
available_hours: DS.attr('number'),
amout: DS.attr('number')
});
项目/New.js路线
export default Ember.Route.extend({
model: function() {
return Ember.RSVP.hash({
projects: this.store.createRecord('project'),
project_details: this.store.createRecord('project_detail')
});
},
actions: {
create: function() {
var self = this;
this.controller.get('model').save().then(
function() {
self.transitionTo('projects.index');
});
}
}
});
项目/New.hbs
<form {{ action "create" on="submit" }}>
<label for="project_name">Project Name</label>
{{ input value=project_name }}
<label for="status">Status</label>
{{ input value=status }}
<label for="feature_name">Feature Name</label>
{{ input value=feature_name }}
<label for="available_hours">Available Hours</label>
{{ input value=available_hours }}
<label for="hours_billed">Hours Billed</label>
{{ input value=hours_billed }}
<label for="amount">Amount</label>
{{ input value=amount }}
<button type="submit">Save</button>
</form>
Router.map(function() {
this.route('home');
this.route('dashboard');
this.route('login');
this.resource('projects', function() {
this.route('new');
this.route('show', {path: '/:id'});
this.route('edit', {path: '/:id/edit'});
});
});
当我提交表单时,似乎调用了操作,但提交的所有数据都是
NULL
,因此很明显,我的输入没有被识别。我已经搜索了几天,还没有看到提交多个模型的解决方案。我的代码是在一篇标准文章上扩展的结果,以及我如何处理通过RSVP散列检索关联模型的问题。任何建议都很好。谢谢 有些东西没有正确连接
当您从您的路线返回以下路线时:
model: function() {
return Ember.RSVP.hash({
projects: this.store.createRecord('project'),
project_details: this.store.createRecord('project_detail')
});
},
setupController(controller, model) {
controller.set('model', model.projects);
controller.set('myProjectDetails', model.project_details);
}
在模板中,您可以使用{{model.something}
来访问该信息,在您的例子中,您可以访问{{model.projects}
和{model.project\u details}
您可能希望在路线中执行以下操作
,以便在模板中设置对模型的更轻松访问
setupController(controller, model) {
//this._super(controller, model) I'll explain why this is commented
controller.set('project', model.projects);
controller.set('project_details', model.project_details);
}
如果执行此操作,则可以在模板中执行以下操作:
<label>Project Name</label>
{{input value=project.project_name}}
{{project.project_name}}
您所做的是将输入
值绑定到控制器的项目名称
属性。如果您使用(提示,如果您不使用它,您应该这样做。它使生活变得更加轻松),您可能可以使用您键入的值检查控制器是否具有该属性project\u name
在Ember 2.0之前,有一个叫做的东西(你不再使用了),它允许将模型代理给控制器。这意味着你可以在你的路线上这样做:
model() {
return this.store.createRecord('project');
}
在模板中,您可以有效地:
<label>Project Name</label>
{{project_name}}
在模板中,您现在可以执行以下操作:
{{ input value=project_name }}
<form {{ action "create" on="submit" }}>
<label for="project_name">Project Name</label>
{{ input value=model.project_name }}
<label for="status">Status</label>
{{ input value=model.status }}
<label for="feature_name">Feature Name</label>
{{ input value=myProjectDetails.feature_name }}
<label for="available_hours">Available Hours</label>
{{ input value=myProjectDetails.available_hours }}
<label for="hours_billed">Hours Billed</label>
{{ input value=myProjectDetails.hours_billed }}
<label for="amount">Amount</label>
{{ input value=amount }}
<button type="submit">Save</button>
</form>
然后您必须将create
操作更改为:
actions: {
create: function() {
var self = this;
this.controller.get('project').save().then(
function() {
self.transitionTo('projects.index');
});
}
}
另外,请注意,您的模型是用
//Project
project_details: DS.hasMany('project_detail', { async: true }),
//Project Detail
project: DS.belongsTo('project', { async: true }),
但是你没有在你发布的代码中设置关系。如果您想让模型相互关联,那么在创建操作中,您需要这样的东西(或者在任何其他地方)。在下面的代码段中,我假设我的setupController
示例位于路由中,因此项目
作为项目
在控制器中,而项目_细节
作为项目_细节
在控制器中
create: function() {
var self = this;
var project = this.controller.get('project');
var projectDetails = this.controller.get('project_details');
project.get('project_details').pushObject(projectDetails);
project_details.set('project', project);
project.save().then(function() {
self.transitionTo('projects.index');
});
}
假设您使用的是Ember Data 2.0,那么这还存在另一个问题。保存项目时
只会发出post请求来保存项目本身(不会保存新创建的项目详细信息
)。目前,JSONAPI
(默认情况下,标准的Ember数据2.0使用)没有一个一次性更新多个资源的解决方案()。这意味着您必须先保存项目详细信息
,然后才保存项目
(查看模型可能没有意义,因为项目详细信息
似乎只存在于项目下
)
据我所知,这是目前的情况。我也在为这个问题寻找一个好的解决方案(我已经拼凑了一些解决方案,比如只允许在项目创建后创建一个项目详细信息,或者在项目中有一个额外的属性,其中包含一个序列化的项目详细信息json字符串,然后拥有它所需要的东西的后端)有些东西没有正确连接 当您从您的路线返回以下路线时:
model: function() {
return Ember.RSVP.hash({
projects: this.store.createRecord('project'),
project_details: this.store.createRecord('project_detail')
});
},
setupController(controller, model) {
controller.set('model', model.projects);
controller.set('myProjectDetails', model.project_details);
}
在模板中,您可以使用{{model.something}
来访问该信息,在您的例子中,您可以访问{{model.projects}
和{model.project\u details}
您可能希望在路线中执行以下操作
,以便在模板中设置对模型的更轻松访问
setupController(controller, model) {
//this._super(controller, model) I'll explain why this is commented
controller.set('project', model.projects);
controller.set('project_details', model.project_details);
}
如果执行此操作,则可以在模板中执行以下操作:
<label>Project Name</label>
{{input value=project.project_name}}
{{project.project_name}}
您所做的是将输入
值绑定到控制器的项目名称
属性。如果您使用(提示,如果您不使用它,您应该这样做。它使生活变得更加轻松),您可能可以使用您键入的值检查控制器是否具有该属性project\u name
在Ember 2.0之前,有一个叫做的东西(你不再使用了),它允许将模型代理给控制器。这意味着你可以在你的路线上这样做:
model() {
return this.store.createRecord('project');
}
在模板中,您可以有效地:
<label>Project Name</label>
{{project_name}}
在模板中,您现在可以执行以下操作:
{{ input value=project_name }}
<form {{ action "create" on="submit" }}>
<label for="project_name">Project Name</label>
{{ input value=model.project_name }}
<label for="status">Status</label>
{{ input value=model.status }}
<label for="feature_name">Feature Name</label>
{{ input value=myProjectDetails.feature_name }}
<label for="available_hours">Available Hours</label>
{{ input value=myProjectDetails.available_hours }}
<label for="hours_billed">Hours Billed</label>
{{ input value=myProjectDetails.hours_billed }}
<label for="amount">Amount</label>
{{ input value=amount }}
<button type="submit">Save</button>
</form>
然后您必须将create
操作更改为:
actions: {
create: function() {
var self = this;
this.controller.get('project').save().then(
function() {
self.transitionTo('projects.index');
});
}
}
另外,请注意,您的模型是用
//Project
project_details: DS.hasMany('project_detail', { async: true }),
//Project Detail
project: DS.belongsTo('project', { async: true }),
但是你没有在你发布的代码中设置关系。如果您想让模型相互关联,那么在创建操作中,您需要这样的东西(或者在任何其他地方)。在下面的代码片段中,我假设我的setupController
示例位于路由中,因此项目作为项目位于控制器中