替换 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:

  1. 启动您的本地 Ember 应用和 API。
  2. 在 Chrome 中打开 localhost:4200。
  3. 在开发工具中打开网络选项卡。
  4. 刷新页面以触发网络请求我假设在您的路由的 model() 挂钩中。
  5. 查看您的 API 返回的 JSON。它 JSON API 合规吗?
  6. 打开 Ember Inspector 中的数据选项卡。
  7. 请求发生后,您希望看到的作者是否出现在商店中?
  8. 如果是,他有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/

然后选择: