【问题标题】:ngResource resolving nested resourcesngResource 解析嵌套资源
【发布时间】:2013-10-24 17:54:22
【问题描述】:

有哪些选项可用于解析 ngResource 响应中的嵌套资源?

有一些关于解决 ngResource 中嵌套资源的端点的相关问题,但这个问题是关于 REST 响应何时包含嵌套在正在查询的集合中的第二个资源,尤其是一对一的映射,你会没有例如pets/<id>/owner 作为自己的资源。

假设有两个资源,Pets 和 Owners:

获取/宠物:

[{
  name: 'spark',
  type: 'dog',
  owner: '/owners/3/' # alternatively just '3' or the full object.
}]

作为一个开发者,我有时想整体查询Owner资源,有时我想查询Pet资源,然后我自动想将owner属性解析为资源实例。

这是我目前的解决方案:

.factory('Pet', function ($resource, Owner) {
  var Pet = $resource('/pets/:id', {id: '@id'});

  Pet.prototype.getOwner = function () {
    return new Owner(this.owner); // or Owner.get({id: this.owner})
  }

  return Pet;
})

这里的问题很多。有诚信——一方面。我相信,这种实现允许同一资源的多个实例。然后是实用性。您还可以跟踪其他属性(owner 和 getOwner(),而不仅仅是 owner;如果您希望能够保存模型,可能是 setOwner)。

可以在 transformResponse 上构建替代解决方案,但将其包含在每个具有嵌套映射的资源中感觉就像是一种黑客攻击。

【问题讨论】:

    标签: angularjs angularjs-resource


    【解决方案1】:

    更新:我最终在这方面工作了一段时间,并开始a new angular module, available on GitHub。下面的答案是关于我最初写的 Gist。

    那里似乎没有我一直在寻找的东西。我已经开始实施仅支持 get 和 getList (query) 操作的解决方案。剩下的方法应该很容易添加,因为我几乎一直使用 ngResource 模块的布局。我的实现要点如下。

    https://gist.github.com/lyschoening/7102262

    资源可以作为完整的对象嵌入到 JSON 中,只需包装在正确的 Resource 模型中,也可以作为 URIs,自动解析。除了嵌入式资源外,该模块还支持典型的嵌套资源,既可以作为真正的父子集合(其中资源只有在选择父资源后才能访问),也可以作为交叉引用的集合。

    Yard = Resource('/yard')     # resource model
    Yard.$nested('trees')        # embedded item or list of items
    
    Chair = Resource('/chair')
    
    Yard.$nested('/chair')      # sub-collection without its own model
                                 # (for many-to-many)
    
    Tree = Resource('/tree')
    
    # child-collection with its own model
    TreeHouse = Tree.$childResource('/treehouse')
    
    
    yard = Yard.get(1)
    # GET /yard/1
    # {
    #    "uri": "/yard/1",
    #    "trees": [
    #       "/tree/15",   -- reference, looked-up automatically with GET
    #       {"uri": "/tree/16", "name": "Apple tree"} 
    #                     -- full object, resolved to Tree instance
    #    ]
    # }
    # GET /tree/16
    # {"uri": "/tree/15", "name": "Pine tree"}
    
    yard.chair.getList()
    # GET /yard/1/chair
    # [{"uri": "/chair/1", ...}, ..]
    # -- model inferred from URI
    
    yard.trees[0].treehouse.getList()
    # GET /tree/15/treehouse
    # [{"uri": "/tree/15/treehouse/1", ...}, ..]
    # -- automatically resolved to TreeHouse instance
    

    【讨论】:

    • 角度模块在哪里?你删了吗?
    • @bruno 修复了link;它与原始评论中的不完全相同,因为它取决于 json-refs。我目前没有进一步维护它,因为我计划用 TypeScript for Angular 2 重写它。它被设计为与 Flask-Potion 一起使用。对于参考解析逻辑的核心,请查看this gist
    【解决方案2】:

    我相信这就是 Martin Gontovnikas 创建 Restangular 的确切原因。他不喜欢在主要的 Angular 框架中处理嵌套的 $resources。我认为他的 Restangular 解决方案非常适合您的需求。他的代码在 GitHub here 上,他在 youtube here 上有一个不错的介绍视频。

    检查一下。我想你会发现它完全符合你的要求。

    【讨论】:

    • 所以你可以在 Restangular 中做的是,调用 Restangular.one('pets', 1).one('owner').get() 并加载 /pets/1/owner。我正在寻找一种范式,其中每个资源都有一个唯一的端点,因此每个所有者都可以访问仅来自/owners/,但同时可以将对象嵌入到不同资源的响应中。
    • Restangular 方式似乎是:pet.owner = Restangular.restangularizeElement(pet, pet.owner, 'owners').
    • 这看起来更像是简单的两个依赖资源,而不是真正的“嵌套”资源。 “嵌套”意味着一个可以从另一个内部访问(意思是一些派生的 url)。拥有两个相互依赖的独立资源(Pet 和 Owner)是不同的。您可以访问后端服务吗?如果后端要预先填充另一个依赖项,似乎依赖项会更好......但这可能是不可能的
    • 我的意思是嵌套在字面上嵌套到响应 JSON 对象中,例如当您有另一个资源的外键时(如我上面的示例所示)。它不一定是父子关系。
    猜你喜欢
    • 1970-01-01
    • 2019-04-30
    • 1970-01-01
    • 2017-06-26
    • 2011-01-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多