鉴于一个模型:
MyModel = Backbone.Model.extend({
defaults: {
name: '',
age: -1,
height: '',
description: ''
}
});
Run Code Online (Sandbox Code Playgroud)
和一个视图将模型呈现为列表:
MyView = Backbone.View.extend({
tagName: 'ul',
className: 'MyView',
render() {
var values = {
name: this.model.get('name'),
age: this.model.get('age'),
height: this.model.get('height'),
description: this.model.get('description')
}
var myTemplate = $('#MyView-Template').html();
var templateWithValues = _.template(myTemplate , values);
}
});
Run Code Online (Sandbox Code Playgroud)
以及View加载的模板:
<script type="text/template" id="MyView-Template">
<li class="name"><%= name %></li>
<li class="age"><%= age %></li>
<li class="name"><%= height%></li>
<li class="name"><%= description%></li>
</script>
Run Code Online (Sandbox Code Playgroud)
一切正常,虽然这是一个人为的例子,真正的代码在模型中有很多很多属性.我遇到的问题是如何处理模型的更新.
我创建了一个HTML表单,其中包含每个字段的相应输入元素.表单被建模并作为模板加载:
<script type="text/template" id="MyEditView-Template">
<input type"text" value="<%= name %>" /> <br />
<input type"text" value="<%= age%>" /> <br />
<input type"text" value="<%= height%>" /> <br />
<input type"text" value="<%= description%>" />
</script>
Run Code Online (Sandbox Code Playgroud)
并加载到视图中:
MyEditView = Backbone.View.extend({
tagName: 'form',
className: 'MyEditView',
render() {
var values = {
name: this.model.get('name'),
age: this.model.get('age'),
height: this.model.get('height'),
description: this.model.get('description')
}
var myTemplate = $('#MyEditView-Template').html();
var templateWithValues = _.template(myTemplate , values);
}
});
Run Code Online (Sandbox Code Playgroud)
当用户保存表单时,新值将在模型(MyModel)中设置.但是我不想重新渲染整个原始视图,它需要太长时间并且有许多嵌套元素.我只想更新模型中值已更改的HTML元素.
问题是我如何优雅地将模型的属性链接到HTML元素,以便我可以对已经渲染的视图执行以下操作:
我有一个相当难看的JavaScript查找表(只是一个对象)的解决方案,它将属性名称映射到HTML元素字符串:
var AttributesMap = {
name: {
htmlRef: 'li.name',
attributeName: 'name'
},
age: {
htmlRef: 'li.age',
attributeName: 'age'
}
...
}
Run Code Online (Sandbox Code Playgroud)
这感觉很糟糕,导致一些非常臃肿的代码.
实际上你的帖子中隐藏着两个问题.您对模型的属性有疑问,并且您不知道如何订阅模型更改事件.幸运的是,使用backbone.js可以轻松实现这两个目标.将您的观看代码更改为以下
render: function () {
var model = this.model;
$(this.el).empty().html(_.template(this.template, this.model.toJSON()))
return this;
}
Run Code Online (Sandbox Code Playgroud)
where el是定义容器的视图的属性.toJSON()是一种可以在模型上调用的方法,用于序列化可以通过线路传输的格式.
视图应该在其初始化函数中订阅模型更改事件,或者更恰当地使用委托事件支持.当模型属性发生更改时,将change在该模型上调用事件,您可以在此处订阅,例如下面的示例.
window.ListView = Backbone.View.extend({
initialize: function () {
//pass model:your_model when creating instance
this.model.on("change:name", this.updateName, this);
this.model.on("change:age", this.changedAge, this);
},
render: function () {
var model = this.model;
$(this.el).empty().html(_.template(this.template, this.model.toJSON()))
return this;
},
updateName: function () {
alert("Models name has been changed");
},
changedAge: function () {
alert("Models age has been changed");
}
});
Run Code Online (Sandbox Code Playgroud)