Backbone.js 中的嵌套模型,如何处理
我已从服务器提供了以下 JSON。有了这个,我想创建一个带有嵌套模型的模型。我不确定哪种方法可以实现这一目标。
//json
[{
name : "example",
layout : {
x : 100,
y : 100,
}
}]
我希望将它们转换为具有以下结构的两个嵌套骨干模型:
// structure
Image
Layout
...
因此,我像这样定义布局模型:
var Layout = Backbone.Model.extend({});
但是我应该使用下面两种(如果有)技术中的哪一种来定义图像模型?下面是A还是B?
A
var Image = Backbone.Model.extend({
initialize: function() {
this.set({ 'layout' : new Layout(this.get('layout')) })
}
});
或, B
var Image = Backbone.Model.extend({
initialize: function() {
this.layout = new Layout( this.get('layout') );
}
});
I've got the following JSON provided from a server. With this, I want to create a model with a nested model. I am unsure of which is the way to achieve this.
//json
[{
name : "example",
layout : {
x : 100,
y : 100,
}
}]
I want these to be converted to two nested backbone models with the following structure:
// structure
Image
Layout
...
So I define the Layout model like so:
var Layout = Backbone.Model.extend({});
But which of the two (if any) techniques below should I use to define the Image model? A or B below?
A
var Image = Backbone.Model.extend({
initialize: function() {
this.set({ 'layout' : new Layout(this.get('layout')) })
}
});
or, B
var Image = Backbone.Model.extend({
initialize: function() {
this.layout = new Layout( this.get('layout') );
}
});
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(12)
我在编写 Backbone 应用程序时遇到了同样的问题。必须处理嵌入式/嵌套模型。我做了一些调整,我认为这是一个非常优雅的解决方案。
是的,您可以修改解析方法来更改对象中的属性,但在我看来,所有这些实际上都是相当难以维护的代码,并且感觉更像是一种黑客而不是解决方案。
这是我对您的示例的建议:
首先像这样定义您的布局模型。
然后这是您的图像模型:
请注意,我没有篡改模型本身,而只是从解析方法传回所需的对象。
当您从服务器读取数据时,这应该确保嵌套模型的结构。现在,您会注意到这里实际上没有处理保存或设置,因为我觉得您使用正确的模型显式设置嵌套模型是有意义的。
像这样:
另请注意,您实际上是通过以下方式调用嵌套模型中的 parse 方法:
您可以根据需要在
model
字段中定义任意数量的嵌套模型。当然,如果您想将嵌套模型保存在自己的表中。这还不够。但在读取和保存整个对象的情况下,这个解决方案应该足够了。
I have the very same issue while I'm writing my Backbone application. Having to deal with embedded/nested models. I did some tweaks that I thought was a quite elegant solution.
Yes, you can modify the parse method to change a attributes around in the object, but all of that is actually pretty unmaintainable code IMO, and feels more of a hack than a solution.
Here's what I suggest for your example:
First define your Layout Model like so.
Then here's your image Model:
Notice that I have not tampered with the model itself, but merely pass back the desired object from the parse method.
This should ensure the structure of the nested model when you're reading from the server. Now, you would notice that saving or setting is actually not handled here because I feel that it makes sense for you to set the nested model explicitly using the proper model.
Like so:
Also take note that you are actually invoking the parse method in your nested model by calling:
You can define as many nested models in the
model
field as you need.Of course, if you want to go as far as saving the nested model in its own table. This wouldn't be sufficient. But in the case of reading and saving the object as a whole, this solution should suffice.
我发布此代码作为 Peter Lyon 建议重新定义解析的示例。我有同样的问题,这对我有用(使用 Rails 后端)。这段代码是用 Coffeescript 编写的。我为不熟悉它的人明确了一些事情。
或者,在 JS 中
I'm posting this code as an example of Peter Lyon's suggestion to redefine parse. I had the same question and this worked for me (with a Rails backend). This code is written in Coffeescript. I made a few things explicit for people unfamiliar with it.
or, in JS
使用 Backbone-associations 中的
Backbone.AssociatedModel
:Use
Backbone.AssociatedModel
from Backbone-associations :我不确定 Backbone 本身是否有推荐的方法来执行此操作。 Layout对象是否有自己的ID并在后端数据库中有记录?如果是这样,您可以将其设为自己的模型。如果没有,您可以将其保留为嵌套文档,只需确保在
save
和parse
方法中正确地将其与 JSON 相互转换即可。如果您最终采取了这样的方法,我认为您的 A 示例与骨干网更加一致,因为set
将正确更新attributes
,但是我再次不确定 Backbone 默认情况下对嵌套模型做了什么。您可能需要一些自定义代码来处理此问题。I'm not sure Backbone itself has a recommended way to do this. Does the Layout object have its own ID and record in the back end database? If so you can make it its own Model as you have. If not, you can just leave it as a nested document, just make sure you convert it to and from JSON properly in the
save
andparse
methods. If you do end up taking an approach like this, I think your A example is more consistent with backbone sinceset
will properly updateattributes
, but again I'm not sure what Backbone does with nested models by default. It's likely you'll need some custom code to handle this.如果你想让事情变得简单,我会选择选项 B。
另一个不错的选择是使用 Backbone-Relational。你只需定义类似的东西:
I'd go with Option B if you want to keep things simple.
Another good option would be to use Backbone-Relational. You'd just define something like:
我使用 Backbone DeepModel 插件来实现嵌套模型和属性。
https://github.com/powmedia/backbone-deep-model
您可以绑定到深度改变事件。例如:
model.on('change:example.nestedmodel.attribute', this.myFunction);
I use Backbone DeepModel plugin for nested models and attributes.
https://github.com/powmedia/backbone-deep-model
You can bind to change events 'n levels deep. for example:
model.on('change:example.nestedmodel.attribute', this.myFunction);
rycfung 漂亮答案的 CoffeeScript 版本:
那不是很甜吗? ;)
CoffeeScript version of rycfung's beautiful answer:
Ain't that sweet? ;)
我遇到了同样的问题,并且一直在尝试 rycfung 的答案中的代码,这是一个很好的建议。
但是,如果您不想直接
设置
嵌套模型,或者不想不断地在
options
中传递{parse: true}
,另一种方法是重新定义set
本身。在Backbone 1.0.0中,
set
在constructor
中调用,unset
,clear
,获取
并保存
。对于需要嵌套模型和/或集合的所有模型,请考虑以下超级模型。
请注意,
model
、_setModel
和_unsetModel
故意留空。在这个抽象级别,您可能无法为回调定义任何合理的操作。但是,您可能希望在扩展CompoundModel
的子模型中覆盖它们。这些回调非常有用,例如,可以绑定侦听器并传播
change
事件。示例:
有了这个,您就可以自动创建嵌套模型和事件传播。还提供并测试了示例用法:
输出:
I had the same issue and I've been experimenting with the code in rycfung's answer, which is a great suggestion.
If, however, you do not want to
set
the nested models directly, or do not want to constantlypass
{parse: true}
in theoptions
, another approach would be to redefineset
itself.In Backbone 1.0.0,
set
is called inconstructor
,unset
,clear
,fetch
andsave
.Consider the following super model, for all models that need to nest models and/or collections.
Notice that
model
,_setModel
and_unsetModel
are left blank on purpose. At this level of abstraction you probably can't define any reasonable actions for the callbacks. However, you may want to override them in the submodels that extendCompoundModel
.Those callbacks are useful, for instance, to bind listeners and propagate
change
events.Example:
With this, you have automatic nested model creation and event propagation. Sample usage is also provided and tested:
Output:
我意识到我参加这个聚会迟到了,但我们最近发布了一个插件来处理这种情况。它称为 backbone-nestify。
因此,您的嵌套模型保持不变:
var Layout = Backbone.Model.extend({...});
然后在定义包含模型时使用插件(使用 Underscore.extend):
之后,假设您有一个模型
m
,它是Image
的实例>,并且您已经设置了 JSON关于m
的问题,你可以这样做:I realize I'm late to this party, but we recently released a plugin to deal with exactly this scenario. It's called backbone-nestify.
So your nested model remains unchanged:
var Layout = Backbone.Model.extend({...});
Then use the plugin when defining the containing model (using Underscore.extend):
After that, assuming you have a model
m
which is an instance ofImage
, and you've set the JSON from the question onm
, you can do:使用backbone-forms
支持嵌套表单、模型和toJSON。全部嵌套
Use backbone-forms
It supports nested forms, models and toJSON. ALL NESTED
如果您不想添加另一个框架,您可以考虑创建一个覆盖
set
和toJSON
的基类,并像这样使用它:您需要
BaseModel
来自此答案(如果您愿意,可以使用作为要点)。If you don't want to add yet another framework, you might consider creating a base class with overridden
set
andtoJSON
and use it like this:You'll need
BaseModel
from this answer (available, if you fancy, as a gist).我们也遇到这个问题,团队工作人员实现了一个名为backbone-nested-attributes的插件。
使用方法非常简单。示例:
这样,树模型就可以访问水果:
您可以在此处查看更多信息:
https:// /github.com/dtmtec/backbone-nested-attributes
We have this problem too and a team worker has implemented a plugin named backbone-nested-attributes.
The usage is very simple. Example:
With this, the Tree model can access then fruits:
You can see more informations here:
https://github.com/dtmtec/backbone-nested-attributes