【问题标题】:ember data no model was found for attribute nameember 数据未找到属性名称的模型
【发布时间】:2026-01-24 04:55:01
【问题描述】:

我已经定义了一个模型(app/models/job.js)

import DS from 'ember-data';

export default DS.Model.extend({
    status: DS.attr(),
    result: DS.attr()
});

我正在尝试从索引控制器(app/controllers/index.js)加载它

import Ember from 'ember';

export default Ember.Controller.extend({
    productName: "",
    customerName: "",
    startDate: "",
    endDate: "",
    actions: {
        search: function() {
            let data = this.store.find("job", '9e5ce869-89b3-4bfc-a70f-034593c21eae');
            return data;
        }
    }
});

我得到的 HTTP 响应是:

{
    "status": "OK",
    "result": {
        "b": 2,
        "a": 2,
        "see": 1,
        "c": 1
    }
}

我如何得到以下错误和警告:

WARNING: Encountered "status" in payload, but no model was found for model name "status" (resolved model name using next-gen-analytics@serializer:job:.modelNameFromPayloadKey("status"))
WARNING: Encountered "result" in payload, but no model was found for model name "result" (resolved model name using next-gen-analytics@serializer:job:.modelNameFromPayloadKey("result"))
TypeError: Cannot read property '_internalModel' of undefined
at finders.js:50
at Object.Backburner.run (ember.debug.js:224)
at ember$data$lib$system$store$$Service.extend._adapterRun (store.js:2043)
at finders.js:45
at tryCatch (ember.debug.js:56151)
at invokeCallback (ember.debug.js:56166)
at publish (ember.debug.js:56134)
at ember.debug.js:32577
at Queue.invoke (ember.debug.js:910)
at Object.Queue.flush (ember.debug.js:974)onerrorDefault @ ember.debug.js:32616exports.default.trigger @ ember.debug.js:56792Promise._onerror @ ember.debug.js:57758publishRejection @ ember.debug.js:56065(anonymous function) @ ember.debug.js:32577Queue.invoke @ ember.debug.js:910Queue.flush @ ember.debug.js:974DeferredActionQueues.flush @ ember.debug.js:770Backburner.end @ ember.debug.js:160Backburner.run @ ember.debug.js:228run @ ember.debug.js:20238ember$data$lib$system$adapter$$default.extend.ajax.Ember.RSVP.Promise.hash.success @ rest-adapter.js:831jQuery.Callbacks.fire @ jquery.js:3148jQuery.Callbacks.self.fireWith @ jquery.js:3260done @ jquery.js:9314jQuery.ajaxTransport.send.callback @ jquery.js:9718

任何建议将不胜感激

更新 我在想这是一个错误,所以我继续在 ember-data github repo 上记录一个错误,在一小时左右得到@wecc 的回复(NICEhttps://github.com/emberjs/data/issues/3683

所以为了解决这个问题,我编写了自己的序列化程序。

import DS from 'ember-data';

export default DS.RESTSerializer.extend({
normalizePayload: function(payload) {
    return {
        'job': {
            id: '9e5ce869-89b3-4bfc-a70f-034593c21eae',
            status: payload.status,
            result: payload.result
        }
    };

}
});

现在,它开始工作了。

意见 我能想到他们为什么以这种方式实现默认的 RESTSerializer,但我们可能应该向用户提供有关 ember-data 文档的更多信息,否则,新手谁正在尝试使用它会迷路。

【问题讨论】:

    标签: ember.js ember-data


    【解决方案1】:

    1) 你的服务器响应应该有一个与模型同名的根元素。因此,对于单个对象,它应该是:

    {
        "job": {
            "id": "<backend must provide an id, integer preferred>"
            "status": "OK",
            "result": {
                "b": 2,
                "a": 2,
                "see": 1,
                "c": 1
            }
    }
    

    对于多个对象:

    {
        "jobs": [{
            "id": "<backend must provide an id, integer preferred>"
            "status": "OK",
            "result": {
                "b": 2,
                "a": 2,
                "see": 1,
                "c": 1
            }, {/*next object*/}]
    }
    

    【讨论】:

    • 我在 ember-data github (github.com/emberjs/data/issues/3683#event-388197850) 中记录了一个错误,从 Christoffer Persson (wecc) 得到了相同的答案。
    • 在我的情况下,我使用的是第三方 api,我不能只要求然后更改 api 响应,有办法将它设置到我身边吗?
    • @RogerRussel 有几种方法。例如,您可以覆盖适配器的handleResponse 方法。或normalize 序列化器方法。我会说序列化程序的normalize 在大多数情况下是正确的选择。
    【解决方案2】:

    我尝试调试它,发现代码转到rest-serializer.js和extractSingle函数,转到“if (!store.modelFactoryFor(modelName)) {”行,它返回“false” .

    extractSingle: function (store, primaryTypeClass, rawPayload, recordId) {
    Ember.deprecate("`serializer.normalizePayload` has been deprecated. Please use `serializer.normalizeResponse` with the new Serializer API to modify the payload.", this.normalizePayload === JSONSerializer.prototype.normalizePayload, {
      id: "ds.serializer.normalize-payload-deprecated",
      until: "2.0.0"
    });
    var payload = this.normalizePayload(rawPayload);
    var primaryRecord;
    
    for (var prop in payload) {
      var modelName = this.modelNameFromPayloadKey(prop);
    
      if (!store.modelFactoryFor(modelName)) {
        Ember.warn(this.warnMessageNoModelForKey(prop, modelName), false, {
          id: "ds.serializer.model-for-key-missing"
        });
        continue;
      }
      var isPrimary = this.isPrimaryType(store, modelName, primaryTypeClass);
      var value = payload[prop];
    

    【讨论】: