【问题标题】:Problems with Accessing Attributes from a nested Backbone.js Model从嵌套 Backbone.js 模型访问属性的问题
【发布时间】:2012-01-11 00:40:21
【问题描述】:

我有一个如下所示的 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});
} 
});

现在我提出了一个模型并将其属性添加到我的集合中:谱号、...、休止符。

当我无法将我的 Collection 传递给 View 时!

我做了这个

路由器:

$(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:

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

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

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

型号:

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

路由器:

....

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

....

【问题讨论】:

  • 嗯,这里发生了几件事,但首先,你的 InitView 代码在哪里?
  • 感谢 JayC!我用视图更新我的帖子!
  • 很高兴你知道了。

标签: javascript backbone.js underscore.js


【解决方案1】:
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 structuring nested views and models

基本上,他建议不要通过集合进行分配,而只需将子模型属性设置为复合模型

所以而不是

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 的“模型”属性下,而不是直接放在Init 下。

【讨论】:

  • 很好的评论 JayC,谢谢你!但是“this.initial.clefs”总是返回“undefined”,真的不明白为什么!无论“谱号”是属性还是属性! :(
【解决方案2】:

这两行完全没有意义:

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

首先,您的路由器中有一个 init 函数,而调用 this.init = new 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") });}
  });

【讨论】:

  • 谢谢安德烈亚斯!我更新我的代码!你的例子我也有错误!!
猜你喜欢
  • 2011-09-08
  • 1970-01-01
  • 1970-01-01
  • 2015-06-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多