gpt4 book ai didi

backbone.js - BackboneJS : View renders fine, 但刷新未定义的集合

转载 作者:行者123 更新时间:2023-12-04 02:52:15 24 4
gpt4 key购买 nike

几周以来,我一直在研究 Backbone,并根据教程制作了一些简单的应用程序。现在我再次从头开始,并尝试使用 Backbone 提供的不错的功能,因为我应该这样做。

虽然我的观点受到了阻碍。当页面加载时,它会很好地呈现并通过迭代集合来创建其嵌套 View 。当我再次调用 render() 来刷新单个条目的整个列表时,所有 View 属性似乎都未定义。

单个条目的模型:

Entry = Backbone.Model.extend({
});

条目列表:(json.html 是数据端的占位符)

EntryCollection = Backbone.Collection.extend({
model: Entry,
url: 'json.html'
});

var entries = new EntryCollection();

单个条目的 View ,它填充了 Underscore 模板并且应该在模型更改时重新呈现自己。

EntryView = Backbone.View.extend({
template: _.template($('#entry-template').html()),
initialize: function(){
this.model.on('change', this.render);
},
render: function(){
this.$el.html(this.template(this.model.toJSON()));
return this;
}
});

查看整个条目列表,它为集合中的每个项目呈现一个 EntryView,如果添加了新项目,则应重新呈现自身。该按钮用于测试目的。

EntryListView = Backbone.View.extend({
tagName: 'div',
collection: entries,
events: {
'click button': 'addEntry'
},
initialize: function(){
this.collection.on('add',this.render);
},
render: function(){
this.$el.append('<button>New</button>'); //to test what happens when a new item is added
var els = [];
this.collection.each(function(item){
els.push(new EntryView({model:item}).render().el);
});
this.$el.append(els);
$('#entries').html(this.el);
return this;
},
addEntry: function(){
entries.add(new Entry({
title: "New entry",
text: "This entry was inserted after the view was rendered"
}));
}
});

现在,如果我从服务器获取集合, View 就可以正常呈现:

entries.fetch({
success: function(model,response){
new EntryListView().render();
}
});

只要我单击按钮将项目添加到集合中,EntryListView 上的事件处理程序就会捕获“添加”事件并调用 render()。但是如果我在渲染函数中设置一个断点,我可以看到所有的属性似乎都是“未定义的”。没有el,没有collection...

我哪里错了?感谢您的帮助,

罗伯特

最佳答案

照原样,EntryListView.render 未绑定(bind)到特定上下文,这意味着范围 (this) 由调用者设置:当您单击您的按钮,这已设置为您的收藏。

您有多种选择来解决您的问题:

  1. 在应用 on 时将正确的上下文指定为第三个参数

    initialize: function(){
    this.collection.on('add', this.render, this);
    },
  2. 使用_.bindAll 将您的render 函数绑定(bind)到您的 View :

    initialize: function(){
    _.bindAll(this, 'render');
    this.collection.on('add', this.render);
    },
  3. 使用 listenTo在调用时为您的函数提供正确的上下文

    initialize: function(){
    this.listenTo(this.collection, 'add', this.render);
    },

你通常会做 2 或/和 3,_.bindAll 给你一个有保证的上下文,listenTo 在你破坏你的 View 时有额外的好处

initialize: function(){
_.bindAll(this, 'render');
this.listenTo(this.collection, 'add', this.render);
},

如果可以的话:

  • 不要在获取回调中创建您的主视图,将其保留在某处引用以便您以后可以对其进行操作
  • 不要在 View 原型(prototype)上声明集合/模型,将它们作为参数传递
  • 不要在 View 中硬连接 DOM 元素,而是将它们作为参数传递

有点像

var EntryListView = Backbone.View.extend({
events: {
'click button': 'addEntry'
},
initialize: function(){
_.bindAll(this, 'render');
this.listenTo(this.collection, 'reset', this.render);
this.listenTo(this.collection, 'add', this.render);
},
render: function(){
var els = [];
this.collection.each(function(item){
els.push(new EntryView({model:item}).render().el);
});

this.$el.empty();
this.$el.append(els);
this.$el.append('<button>New</button>');
return this;
},
addEntry: function(){
entries.add(new Entry({
title: "New entry",
text: "This entry was inserted after the view was rendered"
}));
}
});

var view = new EntryListView({
collection: entries,
el: '#entries'
});
view.render();

entries.fetch({reset: true});

还有一个演示 http://jsbin.com/opodib/1/edit

关于backbone.js - BackboneJS : View renders fine, 但刷新未定义的集合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17446408/

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