gpt4 book ai didi

javascript - 主干模型的转换/初始化子模型

转载 作者:数据小太阳 更新时间:2023-10-29 04:54:26 24 4
gpt4 key购买 nike

我想我有一个非常简单的问题,很难说出来,因此很难找到解决方案。设置:

  • PathCollection 是一个 Backbone.Collection of Paths
  • Path 是一个 Backbone.Model,它包含 NodeCollection(它是一个 Backbone.Collection)和 EdgeCollection(它是一个 Backbone.Collection)。

  • 当我获取 PathCollection
    paths = new PathCollection()
    paths.fetch()

    显然,路径被实例化。但是,我缺少可以允许 Path 从属性哈希实例化其子模型的地方。我真的不能使用解析,对吧?基本上,我在模型实例化并设置属性时寻找模型的入口点。我觉得必须有一些约定。

    最佳答案

    所以我写了几个关于使用 parse() 的答案和 set()实例化和填充子模型和子集合(嵌套数据)。但是,我还没有看到一个真正全面的答案来整合我所看到的许多实践中的一些。当我写很多东西时,我倾向于漫无边际,所以我可能会离题一点,但这可能对遇到类似问题的人有用。

    有几种方法可以做到这一点。使用 parse()是一个。操纵set()是另一个。在您的 initialize() 中实例化这些是另一个。在 Path 模型之外做这一切是另一回事(例如 path = new Path(); path.nodes = new NodeCollection(); 等)

    第二个考虑是这个。您是否希望节点和边集合成为模型属性?还是模型属性?

    哦,这么多选择。很多自由,但有时(令我们沮丧)它使确定“正确方式”变得更加困难。

    由于这种情况经常出现,我将写一篇长篇文章并逐一浏览这些内容。所以请耐心等待我继续更新这个答案。

    在模型之外做 - 简单直接

    当您只在特定模型或集合上需要它时,这通常是添加嵌套模型和集合的简单方法。

    path = new PathModel();

    path.nodes = new NodeCollection();
    path.edge = new EdgeCollection();

    // Continue to set up the nested data URL, etc.

    这是最简单的方法,当您处理不需要定义的一次性模型和集合时效果很好。尽管您可以在对其进行任何操作之前构造此对象的某种方法(例如 View 方法)中轻松生成这些模型。

    使用 initialize()每个模型中的子模型/集合

    如果您知道某个模型的每个实例总是有一个子模型或子集合,那么最简单的设置方法是利用 initialize()功能。

    例如,以您的 Path 模型为例:
    Path = Backbone.Model.extend({
    initialize: function() {
    this.nodes = new NodeCollection();
    this.paths = new PathCollection();

    // Maybe assign a proper url in relation to this Path model
    // You might even set up a change:id listener to set the url when this
    // model gets an id, assuming it doesn't have one at start.
    this.nodes.url = this.id ? 'path/' + this.id + '/nodes' : undefined;
    this.paths.url = this.id ? 'path/' + this.id + '/paths' : undefined;
    }
    });

    现在你的子集合可以像 path.nodes.fetch() 一样被获取它将路由到正确的 URL。十分简单。

    使用 parse()用于实例化和设置子数据

    也许,如果您不想假设每个模型都有一个节点和边集合,它会变得更加棘手。也许只有在 fetch() 时才需要嵌套模型/集合发回这样的数据。这是使用 parse() 的情况可以派上用场。
    parse()的事是它需要任何 json 服务器响应,并且可以在将其传递给模型之前正确命名空间和处理它 set()功能。因此,我们可以检查是否包含模型或集合原始数据并在将响应减少到父模型属性之前对其进行处理。

    例如,也许我们从我们的服务器得到这个响应:
    // Path model JSON example with nested collections JSON arrays
    {
    'name':'orange site',
    'url':'orange.com',
    'nodes':[
    {'id':'1', 'nodeColor':'red'},
    {'id':'2', 'nodeColor':'white'},
    {'id':'3', 'nodeColor':'blue'}
    ],
    'edge':[
    {'id':'1', 'location':'north'},
    {'id':'1', 'location':'south'},
    {'id':'1', 'location':'east'}
    ]
    }

    与默认 parse() Backbone 将吞并它,并为您的路径模型属性“节点”和“边缘”分配一个数组()数据(不是集合)。所以我们要确保我们的 parse()适本地处理这个。
    parse: function(response) {

    // Check if response includes some nested collection data... our case 'nodes'
    if (_.has(response, 'nodes')){

    // Check if this model has a property called nodes
    if (!_.has(this, 'nodes')) { // It does not...
    // So instantiate a collection and pass in raw data
    this.nodes = new NodeCollection(response.nodes);
    } else {
    // It does, so just reset the collection
    this.nodes.reset(response.nodes);
    }

    // Assuming the fetch gets this model id
    this.nodes.url = 'path/' + response.id + '/nodes'; // Set model relative URL

    // Delete the nodes so it doesn't clutter our model attributes
    delete response.nodes;
    }

    // Same for edge...

    return response;
    }

    您也可以使用定制的 set()处理你的子数据。经过多次来回,哪个更好,操纵 set()或在 parse() 中进行我决定我喜欢使用 parse()更多的。但我愿意接受其他人对此的看法。

    使用 set()处理你的子数据

    虽然 parse()依赖于获取数据或使用选项 parse:true 将数据传递到集合中有些人觉得改换 set()功能。同样,我不确定是否有正确的选择,但这是如何工作的。
    set: function(attributes, options) {
    // If we pass in nodes collection JSON array and this model has a nodes attribute
    // Assume we already set it as a collection
    if (_.has(attributes, 'nodes') && this.get("nodes")) {
    this.get('nodes').reset(attributes.nodes);
    delete attributes.nodes;
    } else if (_.has(attributes, 'nodes') && !this.get('nodes')) {
    this.set('nodes', new NodeCollection(attributes.nodes));
    delete attributes.nodes;
    }

    return Backbone.Model.prototype.set.call(this, attributes, options);
    }

    所以如果我们已经有一个属性并且它是一个集合,我们 reset()它。如果我们有一个属性但它不是一个集合,我们就实例化它。在将子数据的 JSON 数组传递给原型(prototype) set() 之前,确保将其正确转换为集合非常重要。 . Backbone,不会将 JSON 数组解释为集合,您只会得到一个直接的数组。

    所以简而言之,你有很多关于如何去做的选择。同样,目前我更喜欢混合使用 initialize()当我知道某些东西总会有那些子模型/系列和 parse()当情况仅需要 fetch() 上可能的嵌套数据时调用。

    关于你的那个问题......(哦,是的,有一个问题)

    您可以允许 Path 以多种方式从散列实例化子模型。我刚刚给了你 4。如果你愿意,你可以使用 parse,如果你知道你会成为 fetch()路径模型或者甚至是一个 pathCollection... pathCollection.fetch({parse:true})有约定吗?也许也许不是。我喜欢根据我认为我将使用模型/集合的上下文使用多种方式的组合。

    我非常愿意讨论其中一些做法以及它们是好是坏。它们只是我在 Stack 上遇到的许多解决方案,并融入了我自己的工作习惯,它们似乎对我来说效果很好。 :-)

    给自己喝杯咖啡,拍拍他的背,那是一篇长文。

    关于javascript - 主干模型的转换/初始化子模型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12350218/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com