JS-数据错误:attrs 必须包含 idAttribute 指定的属性 - 具有 hasMany 关系

问题描述 投票:0回答:1

错误如下: http://puu.sh/lXzja/f773fb6c9a.png

我的用户模型的主键是用户名。我的路线的主键是路线名称。我的 api 根据 jsonapi.org 规范返回 data:{} 内的 json。因此 id 属性并不像 js-data 所要求的那样位于顶层。这就是为什么我在“users”的 afterFind 中返回 data.data 的原因。我尝试在“路线”中做类似的事情,但它是一系列路线。 beforeInject 中的控制台登录给了我:

result in beforeInject

这是配置:

  DS.defineResource({
    name: 'users',
    idAttribute: 'username',
    basePath: apiEndpoint,

    relations: {
        hasMany: {
            routes: {
                localField: 'routes',
                foreignKey: 'username'
            }
        }
    },
    // set just for this resource
    afterFind: function(resource, data, cb) {
        // do something more specific to "users"
        cb(null, data.data);
    }
});

DS.defineResource({
    name: 'routes',
    idAttribute: 'routename',
    basePath: apiEndpoint,
    cacheResponse: true,
    relations: {
        belongsTo: {
            users: {
                parent: true,
                localKey: 'username',
                localField: 'users'
            }
        }
    },
    beforeInject: function(resource, data) {
        // do something more specific to "users"
        console.log(data);
        return data.data.routes;
    }
});

这是我尝试加载路线的地方,但出现错误:

  resolve: {
            user: function($route, DS) {
                var username = $route.current.params.username;
                return DS.find('users', username).then(function(user) {
                    DS.loadRelations('users', user.username, ['routes']).then(function(user) {
                        console.log(user);
                    }, function(err) {
                        console.log(err);
                    });
                });
            }
        }
javascript angularjs jsdata js-data-angular
1个回答
3
投票

您的数据不仅嵌套在“数据”字段下,而且嵌套在“路线”字段下。因此,当您找到路线时,您会尝试注入以下内容:

{
  routes: [{
    // foreignKey to a user
    username: 'john1337',
    // primary key of a route
    id: 1234
  }]
}

当您需要注射时:

[{
  username: 'john1337',
  id: 1
}]

将路线资源上的

afterFindAll
添加到
cb(null, data.data.routes)

您需要:

A)向您的所有资源添加大量“after”挂钩,或者

B) 使反序列化通用,以便它适用于所有资源。也许是这样的?

DS.defaults.afterFind = function (Resource, data, cb) {
  cb(null, data.data[Resource.name])
};
DS.defaults.afterFindAll = function (Resource, data, cb) {
  cb(null, data.data[Resource.name])
};
© www.soinside.com 2019 - 2024. All rights reserved.