我的服务器正在返回一个json数据,使用Ember Data加载模型(page.js,event.js,choice.js)没有问题。但是在提交表单时,提交给服务器的JSON数据不包含相关模型(event.js,choice.js)。
以下是我的文件和json数据。
后端api返回的Json数据:
{
"data": {
"type": "pages",
"id": "12345",
"attributes": {
"guest_id": null,
"name": null,
"email": null,
"address": null
},
"relationships": {"events": {"data": [
{
"type": "events",
"id": "67891"
},
{
"type": "events",
"id": "90908"
}
]}}
},
"included": [
{
"type": "events",
"id": "67891",
"attributes": {
"event_id": "67891",
"name": "Event 1"
},
"relationships": {"choices": {"data": [
{
"type": "choices",
"id": "67891-11111"
},
{
"type": "choices",
"id": "67891-22222"
}
]}}
},
{
"type": "events",
"id": "90908",
"attributes": {
"event_id": "90908",
"name": "Event 2"
},
"relationships": {"choices": {"data": [
{
"type": "choices",
"id": "90908-11111"
},
{
"type": "choices",
"id": "90908-22222"
}
]}}
},
{
"type": "choices",
"id": "67891-11111",
"attributes": {
"choice_id": "67891-11111",
"name": "Diet choice",
"value": "0"
},
"relationships": null
},
{
"type": "choices",
"id": "",
"attributes": {
"choice_id": "67891-22222",
"name": "No. of adult guest",
"value": "0"
},
"relationships": null
}
{
"type": "choices",
"id": "90908-11111",
"attributes": {
"choice_id": "90908-11111",
"name": "Diet choice",
"value": "0"
},
"relationships": null
},
{
"type": "choices",
"id": "90908-22222",
"attributes": {
"choice_id": "90908-22222",
"name": "No. of adult guest",
"value": "0"
},
"relationships": null
}
]
}
提交给服务器的JSON数据
{
"data": {
"id":"e47e8358-0f18-4607-b958-2877155bf5be",
"attributes":{
"guest_id":null,
"name":"my name",
"email":"myemail@gmail.com",
"address":"myaddress"
},
"relationships":{
"events":{
"data":[
{
"type":"events",
"id":"67891"
},
{
"type":"events",
"id":"90908"
}
]
}
},
"type":"pages"
}
}
/pages/show.hbs
<p>
<label>Name: </label>
{{input type="text" value=model.name id="name"}}
</p>
{{#each model.events as |event|}}
<h3>
{{event.name}}
<!-- Rounded switch -->
<label class="switch">
<input type="checkbox" class="switch_input" id="{{event.id}}">
<span class="slider round"></span>
</label>
</h3>
{{#each event.choices as |choice|}}
{{#if (is-equal choice.name "Diet choice")}}
<p>
<label for="diet_choice">{{choice.name}}:</label>
<select id="diet_choice" value=choice.value>
<option value="anything">Anything and Everything</option>
<option value="vegetarian">Vegetarian</option>
<option value="hala">Hala</option>
</select>
</p>
{{/if}}
{{#if (is-equal choice.name "No. of adult guest")}}
<p>
Adult guest
<div>
<button type="button" name="btnMinusGuest" {{action "minusCounter" choice 0 "Minimum 0 guest"}}>-</button>
{{input type="text" value=choice.value}}
<button type="button" name="btnPlusGuest" {{action "addCounter" choice 1 "Maximum 1 guest"}}>+</button>
</div>
</p>
{{/if}}
{{/each}}
{{/each}}
<p>
<label for="email">Email:</label>
{{input type="text" value=model.email}}
</p>
<p>
<label for="address">Address:</label>
{{input type="text" value=model.address}}
</p>
<p>
<input type="submit" name="btnSubmit" value="Submit" {{action "submit"}} />
<input type="submit" name="btnCancel" value="Cancel" {{action "cancel"}} />
</p>
{{outlet}}
/routes/pages/show.js
import Route from '@ember/routing/route';
export default Route.extend({
queryParams: {
event: ''
},
model(params) {
return this.get('store').findRecord('page', params.page_id, { adapterOptions: {query: {'event': params.event}}});
},
actions: {
submit() {
// Create rec
page.save().then(function() {
console.log('submitted');
}).catch(function(reason) {
console.log(reason);
});
},
cancel() {
alert("Are you sure?");
},
addCounter(item, max_val, msg) {
let current_val = parseInt(item.get('value'));
if (current_val >= max_val) {
alert(msg)
} else {
item.set('value', current_val + 1);
}
},
minusCounter(item, min_val, msg) {
let current_val = parseInt(item.get('value'));
if (current_val <= min_val) {
alert(msg);
} else {
item.set('value', current_val - 1)
}
},
}
});
/models/page.js
import DS from 'ember-data';
export default DS.Model.extend({
guest_id: DS.attr(),
name: DS.attr(),
email: DS.attr(),
address: DS.attr(),
is_e_invite: DS.attr(),
data_time_submitted: DS.attr(),
events: DS.hasMany('event')
});
/models/event.js
import DS from 'ember-data';
export default DS.Model.extend({
event_id: DS.attr(),
name: DS.attr(),
choices: DS.hasMany('choice')
});
/models/choice.js
import DS from 'ember-data';
export default DS.Model.extend({
choice_id: DS.attr(),
name: DS.attr(),
value: DS.attr()
});
答案 0 :(得分:0)
解决问题的一种方法是独立保存每个模型,正如@Lux在评论中所说的那样,但您也可以编写一个自定义序列化程序,它将在保存父模型后半手动准备要推送的数据。
假设您正在使用ember-data
,它应该看起来像这样(请参阅https://guides.emberjs.com/v3.0.0/models/customizing-serializers/):
创建一个名为serializers/page.js
的文件并放在那里:
import DS from 'ember-data';
export default DS.RESTSerializer.extend(DS.EmbeddedRecordsMixin, {
attrs: {
events: {embedded: 'save'}
},
serializeIntoHash: function (data, type, record, options) {
const object = this.serialize(record, options);
for (let key in object) {
data[key] = object[key];
}
},
serializeHasMany: function (record, json, relationship) {
const key = relationship.key;
const hasManyRecords = record.hasMany(key);
if (!hasManyRecords || !this.attrs[key] || this.attrs[key].embedded !== 'save') {
return this._super(record, json, relationship);
}
json[key] = [];
hasManyRecords.forEach(item => {
let recordData = item.serialize({includeId: true});
if (relationship.options.deepEmbedded) {
relationship.options.deepEmbedded.forEach(deepKey => {
if (!item.hasMany(deepKey)) {
return true;
}
const deepRecords = item.hasMany(deepKey);
recordData[deepKey] = [];
deepRecords.forEach(deepRecord => {
recordData[deepKey].push(deepRecord.serialize({includeId: true}));
});
});
}
json[key].push(recordData);
});
}
});
并在page
模型中将events: DS.hasMany('event')
更改为events: DS.hasMany('event', {deepEmbedded: ['choices']})
。
以上序列化程序告诉ember-data
将event
的{{1}}作为序列化地图放入page
的输出地图中。此外,对于每个page
,它还会遍历关系的每个event
模型 - 在这种情况下为deepEmbedded
- 并且还会序列化它们。
注意:choices
选项不属于deepEmbedded
,我是根据我的特定需求创建的,因此在每种情况下都可能无法正常运行。