从嵌套 Backbone.js 模型访问属性时出现问题

发布于 2024-12-26 02:40:01 字数 2801 浏览 0 评论 0原文

我有一个如下所示的 JSON 文件:

JSON :

{
 "clefs": [ 
           {"title": "..", "path": ".."},
           ... , 
           {"title": "..", "path": ".."}
          ],

  ....

 "rests": [ 
           {"title": "..", "path": ".."}, 
           ... , 
           {"title": "..", "path": ".."}
          ]

} 

这是一个嵌套的 JSON,对吧?所以我尝试将其转换为嵌套在 Backbone.js 中的模型/集合,如下所示:

Backbone.js :

window.initModel = Backbone.Model.extend({
  defaults: {
    "title": "",
    "path": ""
  }
});

window.CustomCollection = Backbone.Collection.extend({
  model: initModel
});

window.Init = Backbone.Model.extend({
  url : function(){
  return  "/api/data.json"      
},

parse: function(response) {

  clefs = new CustomCollection();
  clefs.add(response.clefs);        
  this.set({clefs: clefs});

  .....

  rests = new CustomCollection();
  rests.add(response.rests);        
  this.set({rests: rests});
} 
});

现在我得到了一个模型并将其属性放入我的集合中:谱号,...,休息。

当需要将我的集合传递给视图时,我不能!

我做了这个

路由器:

$(document).ready(function() {
  var AppRouter = Backbone.Router.extend({
  routes: {
    ""  : "init"
  },

  init: function(){
    this.initial = new Init();      
    this.initialView = new InitView({model: this.initial});
    this.initial.fetch();

 }
});

var app = new AppRouter();
Backbone.history.start();
});

视图:

window.InitView = Backbone.View.extend({
  initialize : function() {
    this.model.bind("reset", this.render, this);//this.model.attributes send my 4 Collections Models back! But impossible to extract with "get" these Attributes

},

  render : function() {
    console.log("render");
  }
});

现在的情况很丑陋!我有一个带有属性(集合)的骨干模型,但我无法提取这些属性,我尝试使用 JSON()、get、_.each、_.map 但没有成功

我想要的是从模型名称的“首字母”中提取我的收藏!! this.initial.attributes 返回一个对象,其中包含我的集合!但我无法将它们传递给视图!

更新 1:

现在 模型 已传递给视图,但我始终无法使用 get 访问他的属性或者将他的属性发送给其他View!渲染器也无法被触发!

更新2: 经过几天的头痛之后,我决定让它变得简单!

为什么?因为我现在只有 4 个集合:谱号、临时记号、音符和休止符

MODEL :

window.initModel = Backbone.Model.extend({
  defaults: {
   "title": "",
   "path": ""
  }
});

window.ClefsCollection = Backbone.Collection.extend({
  model: initModel,
  url: "/api/data.json",
  parse: function(response){
    return response.clefs;
  }
});
...
and so on

ROUTER :

....

this.clefsColl = new ClefsCollection();
this.clefsColl.fetch();
this.clefsCollView = new ClefsView({collection: this.clefsColl});

....

I have a JSON File looking like this:

JSON :

{
 "clefs": [ 
           {"title": "..", "path": ".."},
           ... , 
           {"title": "..", "path": ".."}
          ],

  ....

 "rests": [ 
           {"title": "..", "path": ".."}, 
           ... , 
           {"title": "..", "path": ".."}
          ]

} 

This is a nested JSON, right? So I try to convert that into Model/Collections nested into Backbone.js like this:

Backbone.js :

window.initModel = Backbone.Model.extend({
  defaults: {
    "title": "",
    "path": ""
  }
});

window.CustomCollection = Backbone.Collection.extend({
  model: initModel
});

window.Init = Backbone.Model.extend({
  url : function(){
  return  "/api/data.json"      
},

parse: function(response) {

  clefs = new CustomCollection();
  clefs.add(response.clefs);        
  this.set({clefs: clefs});

  .....

  rests = new CustomCollection();
  rests.add(response.rests);        
  this.set({rests: rests});
} 
});

Now I came out with a Model and into its Attributes my Collection: clefs, ..., rests.

When it's come to pass my Collection to a View I cannot!

I made this

Router :

$(document).ready(function() {
  var AppRouter = Backbone.Router.extend({
  routes: {
    ""  : "init"
  },

  init: function(){
    this.initial = new Init();      
    this.initialView = new InitView({model: this.initial});
    this.initial.fetch();

 }
});

var app = new AppRouter();
Backbone.history.start();
});

View :

window.InitView = Backbone.View.extend({
  initialize : function() {
    this.model.bind("reset", this.render, this);//this.model.attributes send my 4 Collections Models back! But impossible to extract with "get" these Attributes

},

  render : function() {
    console.log("render");
  }
});

It's an ugly situation right now!! I have a Backbone Model with Attributes(Collections) but I can't extract these Attributes, I try with JSON(), get, _.each, _.map but no success!

What i want is to extract my Collections out from the Model name's "initial"!! this.initial.attributes return an Object with my collections into it! but i cannot pass those to the View!

Update 1 :

Now the Model is passed to the View but i always cannot access his attributes with get or send his attributes to other Views! the render can not be fired too!!!

Update 2 :
After several Days of headaches i take the resolution to make it simple!

Why? cause i just have 4 Collections for now : clefs, accidentals, notes and rests

MODEL :

window.initModel = Backbone.Model.extend({
  defaults: {
   "title": "",
   "path": ""
  }
});

window.ClefsCollection = Backbone.Collection.extend({
  model: initModel,
  url: "/api/data.json",
  parse: function(response){
    return response.clefs;
  }
});
...
and so on

ROUTER :

....

this.clefsColl = new ClefsCollection();
this.clefsColl.fetch();
this.clefsCollView = new ClefsView({collection: this.clefsColl});

....

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

森林迷了鹿 2025-01-02 02:40:01
init: function(){
  this.initial = new Init();      
  this.initialView = new InitView({model: this.initial});
  this.initial.fetch();
}

看起来正如我所料,但这:

clefs = new CustomCollection();
clefs.add(response.clefs);        
this.set({clefs: clefs});

没有那么多。我自己也是一个 Backbone.js 新手,所以我仍在学习处理复合模型的最佳方法。我之前所做的是让一个视图跟踪两个模型(因为它显示了一个列表列表,但在任何给定时间只有一个子列表可见)。每当单击第一个列表中的某个项目时,就会选择包含子列表的模型,并从该模型中“获取”字段 toJSON() (这是一个非常不幸的名称,因为它不是 JSON 字符串,而是对象表示形式) ),然后重置绑定到视图的模型以显示当前子列表。如果没有代码,这有点难以解释,但我现在的时间有点短。稍后我可能会尝试更好地解释(也许有另一个答案)。

编辑1

只是为了澄清一下,我反对通过set进行分配,然后通过get进行检索。我只是不确定 Backbone.js 将如何处理这个问题。不过我很想知道。

编辑2

您可能想看看:
backbone.js 构建嵌套视图和模型

基本上,他建议您不要通过 set 进行分配,而只需创建复合模型的子模型属性

,这样

parse: function(response) {

  clefs = new CustomCollection();
  clefs.add(response.clefs);        
  this.set({clefs: clefs});

  .....

您就不必拥有

parse: function(response) {

  this.clefs = new CustomCollection();
  this.clefs.add(response.clefs);
     /*Or maybe you really mean this.clefs.reset(response.clefs)*/

  .....  /* something similar for rests, etc */

}

然后如果您想在路由器中绑定特定视图,假设你已经定义了 CleftsView、RestsView 等。

  init: function(){
    this.initial = new Init();      
    this.initialView = new InitView({model: this.initial});
    this.clefsView = new ClefsView({model: this.initial.clefs});
    this.restsView = new RestsView({model: this.initial.rests});

    .....

    this.initial.fetch();
    .....

  }

我可能之前已经建议过这一点,但我不确定这是否是一种常见做法。我仍然不确定我是否喜欢这个建议,因为我很想将其余和裂口模型放在 Init 的“models”属性下,而不是直接放在 Init 下代码>.

init: function(){
  this.initial = new Init();      
  this.initialView = new InitView({model: this.initial});
  this.initial.fetch();
}

looks as I'd expected, but this:

clefs = new CustomCollection();
clefs.add(response.clefs);        
this.set({clefs: clefs});

Not so much. I'm a bit of a Backbone.js newb myself, so I'm still learning the best way to deal with composite models as well. What I've done previously is have a view keep track of two models (as it showed a list of lists, but with only one of the sublists viewable at any given time). Whenever an item of the first list was clicked, the model containing the sublist was selected, and from that model would "get" the field, toJSON() it (which is a really unfortunate name because it's not a JSON string but the object representation), and then reset a model bound to a view for the current sublist to be displayed. That's a bit hard to explain without code but I'm a little short on time at the moment. Later I may try to explain better (maybe with another answer).

EDIT 1

Just to clarify, my objection was to assigning through set and later retrieving through get. I'm just not sure how Backbone.js would handle that. I'd love to know, though.

EDIT 2

You might want to look at:
backbone.js structuring nested views and models

Basically, he suggests instead of assigning through set, you just make the sub models properties of the composite model

so instead of

parse: function(response) {

  clefs = new CustomCollection();
  clefs.add(response.clefs);        
  this.set({clefs: clefs});

  .....

You'd have

parse: function(response) {

  this.clefs = new CustomCollection();
  this.clefs.add(response.clefs);
     /*Or maybe you really mean this.clefs.reset(response.clefs)*/

  .....  /* something similar for rests, etc */

}

And then if you wanted to bind a specific view, in your Router, assuming you've defined CleftsView, RestsView, etc.

  init: function(){
    this.initial = new Init();      
    this.initialView = new InitView({model: this.initial});
    this.clefsView = new ClefsView({model: this.initial.clefs});
    this.restsView = new RestsView({model: this.initial.rests});

    .....

    this.initial.fetch();
    .....

  }

I might have suggested this earlier, but I wasn't sure if this was a common practice or not. I'mt still not sure if I like the suggestion, as I'd be tempted to put the rests and clefts models under a "models" property of Init instead of directly under Init.

╭ゆ眷念 2025-01-02 02:40:01

这两行根本没有任何意义:

init: function(){
  this.init = new Init();
  this.initView = new InitView({collection: this.init.get("rests") });
  this.init.fetch();

首先,您的 Router 中有一个 init 函数,当调用 this.init = new Init(); 时,将覆盖此函数,因此当再次调用该路由时 init除了你的模型之外,不再圣你的函数。接下来,您创建一个没有任何数据的新模型,因此它是空的。比你尝试从空模型中得到“休息”。之后您填充模型。也许你想要这样的东西:

init: function(){
  //create a new model, fetch the data from the server. On success create a new view passing data from the model.
  var init = new Init().fetch({
      success: function(){new InitView({collection: init.get("rests") });}
  });

This two lines make no sense at all:

init: function(){
  this.init = new Init();
  this.initView = new InitView({collection: this.init.get("rests") });
  this.init.fetch();

First you have a init function in your Router while calling this.init = new Init(); will overwrite this function, so when ever the route is called again init sint your function anymore but your Model. Next you create a new model without any data, so its empty. Than you try to get "rests" out of the empty model. After that you fill the model. Maybe you wanna something like this:

init: function(){
  //create a new model, fetch the data from the server. On success create a new view passing data from the model.
  var init = new Init().fetch({
      success: function(){new InitView({collection: init.get("rests") });}
  });
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文