【问题标题】:Couldn't access related models in ember.js 2.0 using ember-data无法使用 ember-data 访问 ember.js 2.0 中的相关模型
【发布时间】:2015-08-17 21:44:11
【问题描述】:

我正在尝试使用 ember.js 显示一个简单的动态表单,我对 ember 和前端框架来说非常陌生。

我正在使用

  • 灰烬:2.0.0
  • Ember 数据:2.0.0-beta.1
  • jQuery : 1.11.3
  • ember-cli:1.13.6

JSON 负载如下:要生成一些字段并且必须启用一些元素。

JSON:

{
    "create-fields": [{
        "id": 1,
        "field": "widgetName",
        "label": "Widget Name",
        "tooltip": "Widget Name",
        "category": "textfield",
        "url": "",
        "required": true,
        "widgetform_id": 1
    }, {
        "id": 2,
        "field": "APIKey",
        "label": "API Key",
        "tooltip": "API Key",
        "category": "textfield",
        "url": "",
        "required": true,
        "widgetform_id": 1
    }, {
        "id": 3,
        "field": "Campaign",
        "label": "Select Campaign",
        "tooltip": "Select Campaign",
        "category": "select",
        "url": "campaigns/",
        "required": false,
        "widgetform_id": 1
    }, {
        "id": 4,
        "field": "checkbox",
        "label": "Sample Checkbox",
        "tooltip": "Sample Checkbox",
        "category": "checkbox",
        "url": "",
        "required": false,
        "widgetform_id": 1
    }],
    "enable-fields": [{
        "id": 1,
        "field": "showAdvanced",
        "required": false,
        "widgetform_id": 1
    }, {
        "id": 2,
        "field": "notification",
        "required": false,
        "widgetform_id": 1
    }, {
        "id": 3,
        "field": "enableNotif",
        "required": false,
        "widgetform_id": 1
    }, {
        "id": 4,
        "field": "email",
        "required": false,
        "widgetform_id": 1
    }, {
        "id": 5,
        "field": "phone",
        "required": false,
        "widgetform_id": 1
    }, {
        "id": 6,
        "field": "reqType",
        "required": false,
        "widgetform_id": 1
    }, {
        "id": 7,
        "field": "dataFormat",
        "required": false,
        "widgetform_id": 1
    }, {
        "id": 8,
        "field": "appendUrlParams",
        "required": false,
        "widgetform_id": 1
    }],
    "widgetforms": [{
        "id": 1,
        "formname": "Edit Widget",
        "enable-field_ids": [1, 2, 3, 4, 5, 6, 7, 8],
        "create-field_ids": [1, 2, 3, 4]
    }]
}

//模型

widgetform.js:

import DS from 'ember-data';

export default DS.Model.extend({
    formname: DS.attr(),
    createFields: DS.hasMany('createFields'),
    enableFields: DS.hasMany('enableFields')
});

create-field.js:

import DS from 'ember-data';

export default DS.Model.extend({
    field: DS.attr(),
    label: DS.attr(),
    tooltip: DS.attr(),
    category: DS.attr(),
    url: DS.attr('string', {defaultValue: ""}),
    required: DS.attr('boolean'),
    widgetform: DS.belongsTo('widgetform')
});

启用字段.js:

import DS from 'ember-data';

export default DS.Model.extend({
    field: DS.attr(),
    required: DS.attr('boolean'),
    widgetform: DS.belongsTo('widgetform')
});

模板

widgetform.hbs:hbs 没有所有字段,它只是一个模型。

<div class="container-fluid">
{{#each model as |form|}}
<form class="form-horizontal">
<fieldset>
<header id="header">
  <h1>{{form.formname}}</h1>
</header>
<section id="main">
    <ul id="field-list">
        {{form.createFields}}
        {{#each form.createFields as |element|}}
            <li>test1  {{element.field}}</li>
        {{/each}}
    </ul>
</section>
</fieldset>
</form>
{{/each}}
</div>    

到目前为止,我已经能够使用 chrome 中的 ember-inspector 查看各个模型中的数据。

但是,在使用{{form.createFields}} 的模板中,我得到一个&lt;DS.PromiseManyArray&gt;,而{{form.createFields.content}} 是一个&lt;DS.ManyArray&gt; 对象,我无法遍历这两个对象。

我放在模板中的test1 没有打印在页面中。但是,{{form.formname}} 属性可用并打印在页面中。

我检查了很多类似this 的问题,一般建议是添加 id 列表,但我已将它们添加到 JSON 中但我看不出有什么区别

ember-inspector 数据选项卡的屏幕截图:

我在这里做错了什么?有什么想法吗?

【问题讨论】:

  • 我也遇到了同样的问题,有没有其他方法不使用jsonapi...目前使用ember和data 2.0.0,以及活动模型适配器...
  • 我认为这是一些疯狂的环境问题,但如果它被复制,您可以在 ember-data 问题中发布关于此的内容。 github.com/emberjs/data/issues

标签: ember.js ember-data ember-cli


【解决方案1】:

试试createFields: DS.hasMany('createField')(单数)

【讨论】:

  • 我试过了,但我得到了相同的结果。 JSON 不正确还是模型本身不正确,或者我是否以不正确的方式访问它们?困惑:(
  • 除了关系,其他一切都正常吗?您使用的是哪个适配器?你熟悉Ember Inspector吗?那里的“数据”选项卡中的模型有任何异常吗?
  • 其他一切正常。甚至 formname 属性也是从同一个模型中显示的。我可以在 ember inspector 中看到所有三个模型的数据。父模型表示相关模型是计算属性。
【解决方案2】:

您没有指定 Ember Data 在模型之间建立连接所需的关系数据。

create-field.jsenable-field.js 中,您有widgetform: DS.belongsTo('widgetform'),但您没有在记录有效负载上指定widgetform_id: 1。您可以通过在belongsTohasMany 定义中显式设置inverse 选项来解决此问题,但我建议只将关系ID 添加到您的有效负载中。

【讨论】:

  • 你说要在我的所有字段中添加 "widgetform_id": 1,如下所示:"create-fields": [{ "id": 1, "field": "widgetName", "label": "Widget Name", "tooltip": "Widget Name", "category": "textfield", "required": true, "widgetform_id": 1 }
  • @AlanFrancis 正确,ember-data 看到 belongsTo 并希望在记录中找到 &lt;related model&gt;_id 属性。当然,请确保显示正确的 ID 而不是硬编码“1”;-)
  • 我刚开始尝试做一个概念验证,所以 json 是从 ember-cli http-mock 提供的模拟,所以硬编码是这里的方法;)我已经对 JSON 格式进行了更改,但行为没有改变。使用建议的格式更新了 OP。有什么想法吗?
  • 尝试在有效负载中使用带下划线的名称而不是虚线名称,并尝试使用DS.ActiveModelAdapter 作为您的应用程序适配器。
  • 如果没有 ActiveModelAdapter,它将无法工作。无论如何,JSONAPIAdapter 可能是正确的选择,很高兴你让它工作。
【解决方案3】:

由于某种原因,RESTAdapter 不适用于这个特定的数据集或环境,所以我决定放弃它并采用新的 JSONAPI 1.0 规范并使用 JSONAPIAdapter。

型号:

create-field.js:

import DS from 'ember-data';

export default DS.Model.extend({
    field: DS.attr(),
    label: DS.attr(),
    tooltip: DS.attr(),
    category: DS.attr(),
    url: DS.attr('string', { defaultValue: ""}),
    required: DS.attr('boolean')
});

启用字段.js

import DS from 'ember-data';

export default DS.Model.extend({
    field: DS.attr(),
    required: DS.attr('boolean')
});

widgetform.js

import DS from 'ember-data';

export default DS.Model.extend({
    formname: DS.attr(),
    createFields: DS.hasMany('create-field'),
    enableFields: DS.hasMany('enable-field')
});

上述模型的 JSON 格式符合 JSONAPI 1.0 规范:http://jsonapi.org/format/

{
  "data": [{
    "type": "widgetform",
    "id": 1,
    "attributes": {
      "formname": "Edit Widget"
    },
    "relationships": {
      "create-fields": {
        "data": [{
          "type": "create-fields",
          "id": "1"
        }, {
          "type": "create-fields",
          "id": "2"
        }]
      },
      "enable-fields": {
        "data": [{
          "type": "enable-fields",
          "id": "1"
        }, {
          "type": "enable-fields",
          "id": "2"
        }]
      }
    }
  }],
  "included": [{
    "type": "create-fields",
    "id": "1",
    "attributes": {
      "field": "widgetName",
      "label": "Widget Name",
      "tooltip": "Widget Name",
      "category": "textfield",
      "required": true
    }
  }, {
    "type": "create-fields",
    "id": "2",
    "attributes": {
      "field": "APIKey",
      "label": "API Key",
      "tooltip": "API Key",
      "category": "textfield",
      "required": true
    }
  }, {
    "type": "enable-fields",
    "id": "1",
    "attributes": {
      "field": "showAdvanced",
      "required": false
    }
  }, {
    "type": "enable-fields",
    "id": "2",
    "attributes": {
      "field": "notification",
      "required": false
    }
  }]
}

适配器: 应用程序.js

import DS from 'ember-data';

export default DS.JSONAPIAdapter.extend({
    namespace: 'api'
});

我可以像往常一样使用每个块从模板中访问它

widgetform.hbs

<div class="container-fluid">
{{#each model as |form|}}
<form class="form-horizontal">
<fieldset>
<header id="header">
  <h1>{{form.formname}}</h1>
</header>
<section id="main">
    <ul id="field-list">
        {{#each form.createFields as |element|}}
            <li>
                <input name="{{element.field}}" type="text">
            </li>
        {{/each}}
      </ul>
</section>
</fieldset>
</form>
{{/each}}
</div>

我希望它可以帮助某人......

【讨论】:

  • 我也有同样的问题,有没有其他方法不用迁移到json api?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-10-29
  • 1970-01-01
相关资源
最近更新 更多