最近简单用了下backbone,由于backbone不是很熟悉,所以用起来感觉比较别扭。所以把代码发上来想请各位高手看一下,项目后台使用的是dwr。比如我做了一个简单的例子,点击不同的tab后显示不同的列表,我把他们抽象为两套model和view。Model1和View1代表tab的model和view,Model2和View2代表list的model和view。代码如下:
Model.js
var M1=Bckbone.Model.extend({
initialize:function(){
this.getData({实例化时传入的参数});
},
data:null,
promise:$.Deferred(),
getData:function(a,b){
var tThis=this;
BaseController.getTabs(a,b,function(data){
if(data && data.length){
tThis.data=data;
}else{
tThis.data=[];
}
tThis.promise.resolve(tThis); //向view传model
});
}
});
var M2=Bckbone.Model.extend({
initialize:function(){
this.getData({实例化时传入的参数});
},
data:null,
promise:$.Deferred(),
getData:function(a,b){
var tThis=this;
BaseController.getListsFromTabId(a,b,function(data){
if(data && data.length){
tThis.data=data;
}else{
tThis.data=[];
}
tThis.promise.resolve(tThis); //向view传model
});
}
});
View.js
var View1= Backbone.View.extend({
el:'#id1',
initialize:function(model){
this.model=model;
this.render(model);
},
model:null,
render:function(data){
var ele=$(this.$el);
var html='';
ele.find("ul").empty();
/*
*拼接html并显示
*/
},
events:{
"click": //点击事件,点击后调用model2的getData方法,更新model2,并重渲染view2
}
});
var View2= Backbone.View.extend({
el:'#id2',
initialize:function(model){
this.model=model;
this.render(model);
},
model:null,
render:function(data){
var ele=$(this.$el);
var html='';
ele.find("ul").empty();
/*
*拼接html并显示
*/
},
events:{
click:
}
});
main.js
var M1= new Model1({..});
M1.promise.then(function(){
var V1=new View1(M1);
})
.then(function(){
var M2=new Model2({...})
return M2.promise()
})
.then(function(){
var v2=new View2()
})
问题:
1.类似这样的写法该如何实现view与下一个model间的通信?比如最常见的点击tab后切换列表显示,
如果我现在要在view1里面加入一个点击事件,点击后更新model2的data,并再重新渲染view2,这个该怎么做到呢?如果是重新new 一个Model2()会不会造成内存泄露?
高洛峰2017-04-10 16:42:16
不是内存泄露的问题,楼主源码对 Model
的定义就有些许问题了,在 Model.js
中定义了 M1
和 M2
两个模型,在 main.js
又将 M1
和 M2
覆盖掉了。
不过,假设楼主源码没有问题,M1
能够被正常初始化,但会有一个严重的问题,所有的 M1
Model 都会指向同一个 promise
,所以最好是在 initialize
的时候才去指定 promise
属性。
比如 M1
这坨源码:
var M1 = Backbone.Model.extend({
initialize: function() {
this.promise = $.Deferred();
this.fetch(/* 此处应有参数 */);
},
// fetch 函数是 Backbone 推荐的 RESTFUL 风格的 GET
fetch: function(a, b) {
var self = this;
BaseController.getTabs(a, b, function(data) {
self.data = data && data.length ? data : [];
self.promise.resolve(self);
});
}
});
然后 View.js
中,可以使用 listenTo()
方法去监听 Model
的改动,然后去触发一个指定的方法,View1
修改如下:
var View1 = Backbone.View.extend({
el: '#id1',
events: {
'click': 'fetchModelData'
},
// 没有必要传入 model, 因为在初始化 View 的时候传入
// { model: model } Backbone 会自动将 model 填入
initialize: function() {
this.listenTo(this.model, 'change', this.render);
},
render: function() {
// this.$el 本身就是一个 jQuery 对象,不需要再传入 $() 包装
$('ul', this.$el).empty();
// 插♂入 HTML
},
fetchModelData: function() {
this.model.fetch(/* 此处应有参数 */);
}
});
综上,其实 Model
也没有必要插入一个 promise
去执行 View 的初始化操作,将视图建立出来后才交互数据,数据被写入模型之中时会触发 change
事件,因为视图有监听 change
事件,所以也触发了 render()
方法渲染视图。故模型,视图还有初始化视图可以修改如下:
var M1 = Backbone.Model.extend({
// fetch 函数是 Backbone 推荐的 RESTFUL 风格的 GET
fetch: function(a, b) {
var self = this;
BaseController.getTabs(a, b, function(data) {
self.data = data && data.length ? data : [];
self.promise.resolve(self);
});
}
});
var View1 = Backbone.View.extend({
el: '#id1',
events: {
'click': 'fetchModelData'
},
// 没有必要传入 model, 因为在初始化 View 的时候传入
// { model: model } Backbone 会自动将 model 填入
initialize: function() {
this.listenTo(this.model, 'change', this.render);
this.fetchModelData();
},
render: function() {
// this.$el 本身就是一个 jQuery 对象,不需要再传入 $() 包装
$('ul', this.$el).empty();
// 插♂入 HTML
},
fetchModelData: function() {
this.model.fetch(/* 此处应有参数 */);
}
});
var v1 = new View1({ model: new M1() });