替换 Ember.ArrayController.create() 不会解决 belongTo 关系 | ember升级3.x
Replace Ember.ArrayController.create() will not resolve belongTo relationships | ember upgrade 3.x
我正在升级,我遇到了一些问题,因为 ArrayController 已被弃用。
在我的旧 Ember 1.13 路线中,我正在使用
model/announcement.js
export default DS.Model.extend( {
id:DS.attr('string'),
title: DS.attr( 'string' ),
description: DS.attr( 'string' ),
published: DS.attr( 'boolean' ),
publishedAt: DS.attr( 'date' ),
course: DS.belongsTo( 'course' ),
author: DS.belongsTo( 'profile', { async: true } ),
viewed: false,
isNew: true,
}
serializer/announcement.js
import DS from 'ember-data';
import ApplicationSerializer from 'mim/serializers/application';
export default ApplicationSerializer.extend( DS.EmbeddedRecordsMixin, {
keyForRelationship: function( key ) {
return key !== 'author' ? key : 'id';
}
} );
routes/announcement.js
setupController: function( controller, model ) {
this._super( ...arguments );
var announcements = Ember.ArrayController.create( {
model: model,
sortProperties: [ 'publishedAt' ],
sortAscending: false
} );
controller.set( 'model', announcements );
},
在路由公告的控制器中,如下:
controller/announcement.js
publishedAnnouncements: Ember.computed( 'model.[]', 'model.@each.published', 'model.@each.viewed', function() {
var published = this.get( 'model' ).filterBy( 'published', true ),
announcements = Ember.A();
announcements.pushObjects( published.filterBy( 'viewed', false ) );
announcements.pushObjects( published.filterBy( 'viewed' ) );
return announcements;
} ),
因此在模板 im 运行 中为每个循环呈现所有公告,如
templates/announcements.hbs
{{#each publishedAnnouncements as |announcement|}}
{{announcement.author.firstName}}
{{/each}}
在 ember 升级 3.5 后,我将这些更改为以下内容:
model/announcement.js
export default DS.Model.extend( {
id:DS.attr('string'),
title: DS.attr( 'string' ),
description: DS.attr( 'string' ),
published: DS.attr( 'boolean' ),
publishedAt: DS.attr( 'date' ),
course: DS.belongsTo( 'course' ),
// 从配置文件中删除 async true
author: DS.belongsTo( 'profile'),
viewed: false,
isNew: true,
}
serializer/announcement.js
import DS from 'ember-data';
import ApplicationSerializer from 'mim/serializers/application';
export default ApplicationSerializer.extend( DS.EmbeddedRecordsMixin, {
keyForRelationship: function( key ) {
return key !== 'author' ? key : 'id';
}
} );
routes/announcement.js
setupController: function( controller, model ) {
this._super( ...arguments );
//removed arrayController from here and assigned model
controller.set( 'model', model );
},
controller/announcement.js
排序属性:['publishedAt:desc'],
sortedModel: computed.sort('model', 'sortProperties'),
publishedAnnouncements: Ember.computed( 'model.[]', 'model.@each.published', 'model.@each.viewed', function() {
//getting model by local computed property defined above.arrayController sort is doing with above method by sortPropteries
var published =this.get('sortedModel').filterBy( 'published', true);
announcements = Ember.A();
announcements.pushObjects( published.filterBy( 'viewed', false ) );
announcements.pushObjects( published.filterBy( 'viewed' ) );
return announcements;
} ),
templates/announcements.hbs
{{#each publishedAnnouncements as |announcement|}}
{{announcement.author.firstName}}
{{/each}}
然后 announcement.author.firstname
在 ember 3.5 中未定义
但如果它不是 belongsTo 关系,它将在那里(例如 announcement.publishedAt
)
我不知道我错过了什么或者我做错了什么。
我在此处附上控制台日志的屏幕截图,这是我在控制器发布的变量中所做的。
Ember 1.13
Ember 3.5
你的回答让我更好地理解了这个问题。 api returns 自定义版本的数据,这就是 embeddedRecordsMixin 使用的原因 这是课程 api 有效负载
{
"courses": [{
"created_at": "2016-11-22T09:37:53+00:00",
"updated_at": "2016-11-22T09:37:53+00:00",
"students": ["01", "02"],
"coordinators": ["001", "002"],
"programme_id": 1,
"announcements": [{
"created_at": "2016-11-23T08:27:31+00:00",
"updated_at": "2016-11-23T08:27:31+00:00",
"course_id": 099,
"id": 33,
"title": "test announcement",
"description": "please ignore",
"published_at": "2016-11-23T08:27:31+00:00",
"published": true
}, {
"created_at": "2016-11-25T07:13:18+00:00",
"updated_at": "2016-11-25T07:13:18+00:00",
"course_id": 04,
"id": 22,
"title": "test before ",
"description": "test",
"published_at": "2016-11-25T07:13:18+00:00",
"published": true
}]
}
从哪里开始调试:
看看你的API returns:
- 启动您的本地 Ember 应用和 API。
- 在 Chrome 中打开 localhost:4200。
- 在开发工具中打开网络选项卡。
- 刷新页面以触发网络请求我假设在您的路由的
model()
挂钩中。
- 查看您的 API 返回的 JSON。它 JSON API 合规吗?
- 打开 Ember Inspector 中的数据选项卡。
- 请求发生后,您希望看到的作者是否出现在商店中?
- 如果是,他有
firstName
还是未定义?
如果一切都是肯定的,那么我们可能可以排除请求、API 和序列化程序的问题。
看到这个序列化程序:
// app/serializers/announcments.js
import DS from 'ember-data';
import ApplicationSerializer from 'mim/serializers/application';
export default ApplicationSerializer.extend( DS.EmbeddedRecordsMixin, {
keyForRelationship: function( key ) {
return key !== 'author' ? key : 'id';
}
} );
mixin EmbeddedRecordsMixin
暗示了你的 API returns 嵌入数据,这对于 JSON API 兼容响应来说是非常罕见的。如果全部符合 this spec:
,这是您唯一需要的序列化程序
// app/serializers/application.js
import JSONAPISerializer from 'ember-data/serializers/json-api';
export default JSONAPISerializer.extend({});
来自您 API 的数据应该如下所示:
{
"data": [{
"type": "announcement",
"id": "1",
"attributes": {
"message": "...",
},
"relationships": {
"author": {
"data": { "type": "profile", "id": "9" }
},
}
}],
"included": [{
"type": "profile",
"id": "9",
"attributes": {
"firstName": "John",
"lastName": "Johnson"
},
}]
}
Ember 旨在与后端无关。使用 serialisers you can convert all JSON from incoming server responses to suit the Ember Data store. Similarily you use adapters 转换传出服务器请求以适合您的后端。
我推荐阅读此文档:
https://guides.emberjs.com/release/models/customizing-serializers/
然后选择:
我正在升级,我遇到了一些问题,因为 ArrayController 已被弃用。
在我的旧 Ember 1.13 路线中,我正在使用
model/announcement.js
export default DS.Model.extend( {
id:DS.attr('string'),
title: DS.attr( 'string' ),
description: DS.attr( 'string' ),
published: DS.attr( 'boolean' ),
publishedAt: DS.attr( 'date' ),
course: DS.belongsTo( 'course' ),
author: DS.belongsTo( 'profile', { async: true } ),
viewed: false,
isNew: true,
}
serializer/announcement.js
import DS from 'ember-data';
import ApplicationSerializer from 'mim/serializers/application';
export default ApplicationSerializer.extend( DS.EmbeddedRecordsMixin, {
keyForRelationship: function( key ) {
return key !== 'author' ? key : 'id';
}
} );
routes/announcement.js
setupController: function( controller, model ) {
this._super( ...arguments );
var announcements = Ember.ArrayController.create( {
model: model,
sortProperties: [ 'publishedAt' ],
sortAscending: false
} );
controller.set( 'model', announcements );
},
在路由公告的控制器中,如下:
controller/announcement.js
publishedAnnouncements: Ember.computed( 'model.[]', 'model.@each.published', 'model.@each.viewed', function() {
var published = this.get( 'model' ).filterBy( 'published', true ),
announcements = Ember.A();
announcements.pushObjects( published.filterBy( 'viewed', false ) );
announcements.pushObjects( published.filterBy( 'viewed' ) );
return announcements;
} ),
因此在模板 im 运行 中为每个循环呈现所有公告,如
templates/announcements.hbs
{{#each publishedAnnouncements as |announcement|}}
{{announcement.author.firstName}}
{{/each}}
在 ember 升级 3.5 后,我将这些更改为以下内容:
model/announcement.js
export default DS.Model.extend( {
id:DS.attr('string'),
title: DS.attr( 'string' ),
description: DS.attr( 'string' ),
published: DS.attr( 'boolean' ),
publishedAt: DS.attr( 'date' ),
course: DS.belongsTo( 'course' ),
// 从配置文件中删除 async true
author: DS.belongsTo( 'profile'),
viewed: false,
isNew: true,
}
serializer/announcement.js
import DS from 'ember-data';
import ApplicationSerializer from 'mim/serializers/application';
export default ApplicationSerializer.extend( DS.EmbeddedRecordsMixin, {
keyForRelationship: function( key ) {
return key !== 'author' ? key : 'id';
}
} );
routes/announcement.js
setupController: function( controller, model ) {
this._super( ...arguments );
//removed arrayController from here and assigned model
controller.set( 'model', model );
},
controller/announcement.js
排序属性:['publishedAt:desc'], sortedModel: computed.sort('model', 'sortProperties'),
publishedAnnouncements: Ember.computed( 'model.[]', 'model.@each.published', 'model.@each.viewed', function() {
//getting model by local computed property defined above.arrayController sort is doing with above method by sortPropteries
var published =this.get('sortedModel').filterBy( 'published', true);
announcements = Ember.A();
announcements.pushObjects( published.filterBy( 'viewed', false ) );
announcements.pushObjects( published.filterBy( 'viewed' ) );
return announcements;
} ),
templates/announcements.hbs
{{#each publishedAnnouncements as |announcement|}}
{{announcement.author.firstName}}
{{/each}}
然后 announcement.author.firstname
在 ember 3.5 中未定义
但如果它不是 belongsTo 关系,它将在那里(例如 announcement.publishedAt
)
我不知道我错过了什么或者我做错了什么。
我在此处附上控制台日志的屏幕截图,这是我在控制器发布的变量中所做的。
Ember 1.13
Ember 3.5
你的回答让我更好地理解了这个问题。 api returns 自定义版本的数据,这就是 embeddedRecordsMixin 使用的原因 这是课程 api 有效负载
{
"courses": [{
"created_at": "2016-11-22T09:37:53+00:00",
"updated_at": "2016-11-22T09:37:53+00:00",
"students": ["01", "02"],
"coordinators": ["001", "002"],
"programme_id": 1,
"announcements": [{
"created_at": "2016-11-23T08:27:31+00:00",
"updated_at": "2016-11-23T08:27:31+00:00",
"course_id": 099,
"id": 33,
"title": "test announcement",
"description": "please ignore",
"published_at": "2016-11-23T08:27:31+00:00",
"published": true
}, {
"created_at": "2016-11-25T07:13:18+00:00",
"updated_at": "2016-11-25T07:13:18+00:00",
"course_id": 04,
"id": 22,
"title": "test before ",
"description": "test",
"published_at": "2016-11-25T07:13:18+00:00",
"published": true
}]
}
从哪里开始调试:
看看你的API returns:
- 启动您的本地 Ember 应用和 API。
- 在 Chrome 中打开 localhost:4200。
- 在开发工具中打开网络选项卡。
- 刷新页面以触发网络请求我假设在您的路由的
model()
挂钩中。 - 查看您的 API 返回的 JSON。它 JSON API 合规吗?
- 打开 Ember Inspector 中的数据选项卡。
- 请求发生后,您希望看到的作者是否出现在商店中?
- 如果是,他有
firstName
还是未定义?
如果一切都是肯定的,那么我们可能可以排除请求、API 和序列化程序的问题。
看到这个序列化程序:
// app/serializers/announcments.js
import DS from 'ember-data';
import ApplicationSerializer from 'mim/serializers/application';
export default ApplicationSerializer.extend( DS.EmbeddedRecordsMixin, {
keyForRelationship: function( key ) {
return key !== 'author' ? key : 'id';
}
} );
mixin EmbeddedRecordsMixin
暗示了你的 API returns 嵌入数据,这对于 JSON API 兼容响应来说是非常罕见的。如果全部符合 this spec:
// app/serializers/application.js
import JSONAPISerializer from 'ember-data/serializers/json-api';
export default JSONAPISerializer.extend({});
来自您 API 的数据应该如下所示:
{
"data": [{
"type": "announcement",
"id": "1",
"attributes": {
"message": "...",
},
"relationships": {
"author": {
"data": { "type": "profile", "id": "9" }
},
}
}],
"included": [{
"type": "profile",
"id": "9",
"attributes": {
"firstName": "John",
"lastName": "Johnson"
},
}]
}
Ember 旨在与后端无关。使用 serialisers you can convert all JSON from incoming server responses to suit the Ember Data store. Similarily you use adapters 转换传出服务器请求以适合您的后端。
我推荐阅读此文档:
https://guides.emberjs.com/release/models/customizing-serializers/
然后选择: