Ember-Data:如何使用“mappings”?

11
我是一名有用的助手,可以为您进行文本翻译。以下是需要翻译的内容:

我目前正在尝试使用ember + emberdata + router + asp.net web api搭建一个项目。大部分都能正常运行,但是当ember-data通过适配器查找我的模型时,我遇到了一个错误信息。

在我的后端,我有一个像这样的模型(C#):

public class Genre {
    [Key]
    public int Id { get; set; }
    [Required]
    [StringLength(50, MinimumLength=3)]
    public string Name { get; set; }
}

在我的应用程序中,我使用Ember-data来表示它:

App.Genre = DS.Model.extend({
    id: DS.attr("number"),
    name: DS.attr("string")
}).reopenClass({
    url: 'api/genre'
});

我在应用程序中使用RESTAdapter定义了一个商店,如下所示:

App.store = DS.Store.create({
    revision: 4,
    adapter: DS.RESTAdapter.create({
        bulkCommit: false
    })
});

并且在我的控制器中使用该存储库如下:

App.GenreController = Ember.ArrayController.extend({
    content: App.store.findAll(App.Genre),
    selectedGenre: null
});

路由器被定义为:
App.router = Em.Router.create({
    enableLogging: true,
    location: 'hash',
    root: Ember.Route.extend({
        //...

        genre: Em.Route.extend({
            route: '/genre',
            index: Ember.Route.extend({
                connectOutlets: function (router, context) {
                    router.get('applicationController').connectOutlet('genre');
                }
            })
        }),

        //...
    })
})

当我运行我的应用程序时,每个具有相同结构的对象都会出现以下消息:

Uncaught Error: assertion failed: 服务器返回了一个哈希键为0但您没有映射

供参考,这是服务返回的json数据:
[
  {
    "id": 1,
    "name": "Action"
  },
  {
    "id": 2,
    "name": "Drama"
  },
  {
    "id": 3,
    "name": "Comedy"
  },
  {
    "id": 4,
    "name": "Romance"
  }
]

我无法确定问题的具体原因,但由于断言提到需要映射,我想知道:
  1. 这个映射是什么以及如何使用它。
  2. 由于返回的json是一个数组,我是否应该在我的应用程序中使用不同类型的控制器,或者在使用这种类型的json时是否需要了解任何信息?或者我应该更改服务器中的JsonFormatter选项?
欢迎任何帮助。
如果您认为这不足以理解问题,我肯定可以添加更多信息。
编辑:我已经在后端更改了一些内容,现在我的服务器上的findAll()等效操作将输出序列化为以下json:
{
  "genres": [
      { "id": 1, "name": "Action" },
      { "id": 2, "name": "Drama" },
      { "id": 3, "name": "Comedy" },
      { "id": 4, "name": "Romance" }
   ]
}

但是我仍然无法在客户端中填充我的模型,而且我的错误消息已经变成了这样:

未捕获的错误: 断言失败: 您的服务器返回了一个带有键 genres 的哈希表,但您没有映射

不确定我还会做错什么。

抛出此异常的方法是sideload,并像这样检查映射:

sideload: function (store, type, json, root) {
        var sideloadedType, mappings, loaded = {};

        loaded[root] = true;

        for (var prop in json) {
            if (!json.hasOwnProperty(prop)) { continue; }
            if (prop === root) { continue; }

            sideloadedType = type.typeForAssociation(prop);

            if (!sideloadedType) {
                mappings = get(this, 'mappings');
                Ember.assert("Your server returned a hash with the key " + prop + " but you have no mappings", !!mappings);
//...

这个调用 sideloadedType = type.typeForAssociation(prop); 返回 undefined,然后我收到了错误消息。方法 typeForAssociation() 检查 'associationsByName' 键是否存在,返回一个空的 Ember.Map

目前还没有解决方案。

顺便说一下...

我的操作现在是这样的:

    // GET api/genres
    public object GetGenres() {
        return new { genres = context.Genres.AsQueryable() };
    }

    // GET api/genres
    //[Queryable]
    //public IQueryable<Genre> GetGenres()
    //{
    //    return context.Genres.AsQueryable();
    //}

我不得不删除原始实现,这个实现被json.NET序列化。我找不到配置选项来产生Ember-Data期望的json输出(如{resource_name : [json, json,...]})。这个副作用是我失去了内置的OData支持,但我希望保留它。有人知道我该如何配置它来为集合生成不同的json吗?
3个回答

12

这个映射可以在DS.RESTAdapter中定义。我认为你可以尝试定义类似下面的内容:

App.Store = DS.Store.extend({
  adapter: DS.RESTAdapter.create({
    bulkCommit: true,
    mappings: {
      genres: App.Genre
    },
    // you can also define plurals, if there is a unregular plural
    // usually, RESTAdapter simply add a 's' for plurals.
    // for example at work we have to define something like this
    plurals: {
      business_process: 'business_processes' 
      //else it tries to fetch business_processs
    }
  }),
  revision: 4
});
希望这解决了你的问题。
更新:
目前为止,这并没有被很好地记录下来,我不记得我们是通过阅读代码自己找到的,还是或许Tom Dale指出了它。
无论如何,在这里可以看到复数形式的关键点。 对于映射,我认为我们受到了与你相同的错误驱动,我们要么尝试了,要么Tom教给了我们这个。

两个答案都很有帮助,我想我真的不知道在哪里设置映射。现在,我终于要开始使用视图和模板了。谢谢Sylvain。 - MilkyWayJoe
最后一件事,我找不到关于“映射”的具体信息。你能指出我在哪里可以找到吗?如果只有在源代码中,那么它应该可以/应该在自述文件中提供。 - MilkyWayJoe

8

我设法让我的服务以相同的格式生成JSON,但现在我收到了消息“未捕获的错误:断言失败:您的服务器返回一个具有键genres但您没有映射的哈希”。我设法使用不同的控制器/模型加载Ember 0.9.1,而没有使用Ember-data。 - MilkyWayJoe
很遗憾,它不是json格式,现在我返回了上面指定的格式,现在我得到了另一个属性的相同消息,而不再是索引。 - MilkyWayJoe

3

我正在使用Ember Data rev. 11,似乎DS.RESTAdapter.create中的plurals配置从未生效。我查看了代码并找到了以下解决方案:

App.Adapter = DS.RESTAdapter.extend({
  bulkCommit: false
})

App.Adapter.configure('plurals', {
  series: 'series'
})

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接