替换Ember.ArrayController.create()将无法解析归属关系|灰烬升级3.x

时间:2018-11-12 04:00:52

标签: javascript ember.js ember-data ember-router ember-controllers

我正在升级过程中,由于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;
  } ),

因此在模板中,我为每个循环运行a以呈现所有公告,如

templates / announcements.hbs

  {{#each publishedAnnouncements as |announcement|}}
        {{announcement.author.firstName}}
      {{/each}} 

灰烬升级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' ),

///从配置文件中删除异步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

sortProperties:['publishedAt:desc'],   sortedModel:compute.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中未定义 但如果它不是归属关系,那么它将存在(例如announcement.publishedAt

我不知道我错过了什么或做错了什么。

我将在此处附加控制台日志的屏幕截图,该截图是我在控制器发布的变量中所做的。

琥珀色1.13

enter image description here

灰烬3.5 enter image description here

您的回答使我更好地理解了问题。该API返回的是数据的自定义版本,这就是为什么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
    }]
}

2 个答案:

答案 0 :(得分:1)

从哪里开始调试:

看看您的API返回什么:

  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返回嵌入式数据,这对于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"
    },
  }]
}

答案 1 :(得分:1)

Ember设计为不可知的后端。使用serialisers,您可以将来自传入服务器响应的所有JSON转换为适合Ember Data存储的格式。同样,您使用adapters来转换传出服务器请求以适合您的后端。

我建议阅读此文档:

https://guides.emberjs.com/release/models/customizing-serializers/

然后从以下选项中进行选择: