主干子视图事件没有触发,访问这个.模型丢失
Backbone subview event doesn't fire, access to this.model lost
我使用一个主视图与子视图与它自己的子视图,我失去了子视图上的事件。
在SO中,它看起来像一个delegateEvents是需要的,但我不知道如何或在哪里。
另外,把tbody: tbodyEl[ "0" ].outerHTML
传递给我的模板似乎真的很糟糕,但我不知道它是否与事件问题有关。
任何帮助都非常感谢。
mainView:
return Backbone.View.extend({
el: "#content",
initialize: function () {
this.render();
},
render: function () {
var todosView = new TodosView({
collection: projectCol
});
}
});
todosView:
return Backbone.View.extend({
el: "#content-body",
template: _.template([
'<div class="table-responsive">',
'<table id="todo-table" class="table">',
'<span class="caption">Top <%= project %> Tasks <a id="<%= project %>" class="projectName">(See All)</span></a>',
'<thead>',
'<tr>',
'<th>Task</th>',
'<th>Due</th>',
'</tr>',
'</thead>',
'<%= tbody %>',
'</table>',
'</div>'
].join("")),
initialize: function () {
this.render();
},
render: function () {
var projectName = this.collection.models[0].attributes.project;
var tbodyEl = $("<tbody />");
this.collection.each(function (item) {
var todoView = new TodoView({
model: item
});
tbodyEl.append(todoView.el);
});
this.$el.append(this.template({
project: projectName,
tbody: tbodyEl["0"].outerHTML
}));
}
});
todoView:
return Backbone.View.extend({
tagName: "tr",
className: "todo-rec",
template: _.template([
"<td>",
"<label id='task' class='edit'><%= task %></label>",
"<input id='edited-task' class='new-edit' style='display:none;' value='<%= task %>'>",
"</td>",
"<td>",
"<span id='due' class='edit'><%= due %></span>",
"<input id='edited-due' class='new-edit' style='display:none;' value='<%= due %>'>",
"</td>",
].join("")),
events: {
"click .edit": "editFields"
},
initialize: function () {
this.render();
},
render: function () {
this.$el.html(this.template(this.model.toJSON()));
return this;
},
editFields: function () {
console.log("todoView: editFields clicked"); // <-- does not fire
}
});
25 Oct更新:感谢@WinterSoldier,这就是我最终得到的:代码构建元素在插入DOM和todoView之前完成。事件的工作,给予完全访问这个。模特,另外,它看起来更"骨气":
// mainView:
return Backbone.View.extend( {
el: "#content",
initialize: function(){
this.render();
},
render: function(){
$( "#content-body" ).empty();
var section = new TodosView( { collection: projectCol } ); // should be returning a section div
$( "#content-body" ).append( section.el );
}
} );
// todosView:
return Backbone.View.extend( {
// used tagName so the element can be built complete before inserting into DOM
tagName: "div",
className: "table-responsive",
// tbody changed to empty element
template: _.template( [
'<table id="todo-table" class="table">',
'<span class="caption">Top <%= project %> Tasks <a id="<%= project %>" class="projectName">(See All)</span></a>',
'<thead>',
'<tr>',
'<th>Comp.</th>',
'<th>Task</th>',
'<th>Due</th>',
'<th>Priority</th>',
'<th>Delegated To</th>',
'<th>Project</th>',
'<th>Del.</th>',
'</tr>',
'</thead>',
'<tbody id="tbodyContent"></tbody>',
'</table>' ].join( "" )
),
initialize: function(){
this.render();
},
render: function(){
// new: render the template first, then append rows in #tbody
var projectName = this.collection.models[ 0 ].attributes.project;
this.$el.empty().html( this.template( {
project: projectName
} ) );
var this2 = this;
this.collection.each( function( item ){
var todoView = new TodoView( {model: item} );
this2.$el.find( "#tbodyContent" ).append( todoView.el );
} );
// now returning a <div class="table-responsive" with all rows
return this;
}
} );
// todoView:
// Note: nothing changed from original code
return Backbone.View.extend( {
tagName: "tr",
className: "todo-rec",
template: _.template( [
"<td>",
"<label id='task' class='edit'><%= task %></label>",
"<input id='edited-task' class='new-edit' style='display:none;' value='<%= task %>'>",
"</td>",
"<td>",
"<span id='due' class='edit'><%= due %></span>",
"<input id='edited-due' class='new-edit' style='display:none;' value='<%= due %>'>",
"</td>",
].join( "" )
),
events: {
"click .edit": "editFields"
},
initialize: function() {
this.render();
},
render: function() {
this.$el.html( this.template( this.model.toJSON() ) );
return this;
},
editFields: function() {
console.log( "todoView: editFields clicked", this );
}
} );
让我列出我根据这个问题所做的假设:
- 模板渲染没有问题
- 模板代码可以用纯html代替事件发射。
基于这些假设,我创建了一个具有两个模型的集合,并将它们传递给TodosView,从中我迭代这些模型以生成行视图-在那里通过将其添加到'tbody'标记。
请跟着这里的小提琴走=>https://jsfiddle.net/randomfifaguy/304kffed/1/
console.log("hello");
Test = Backbone.Model.extend({});
var testModel1 = new Test({
'task': 'taskA',
'due': 'dueByZ'
})
var testModel2 = new Test({
'task': 'taskB',
'due': 'dueByY'
})
console.log(testModel1.get('task'));
console.log(testModel2.get('task'));
ModelCollection = Backbone.Collection.extend({});
var models = new ModelCollection([testModel1, testModel2]);
console.log(models);
TodosView = Backbone.View.extend({
el: "#content-body",
initialize: function() {
this.render();
},
render: function() {
var templ = "<div class='table-responsive'><table id='todo-table'class='table'><span class='caption'>Top Tasks <a id='<%= project %>' class='projectName'>(See All)</span></a><thead><tr><th>Task</th><th>Due</th></tr></thead><tbody></tbody></table></div>";
$(this.el).html(templ);
_.each(this.collection.models, function(mdl){
var view = new TodoView({
model: mdl
});
$('tbody').append(view.el);
});
}
});
MainView = Backbone.View.extend({
el: "#content",
initialize: function() {
this.render();
},
render: function() {
new TodosView({
collection: models
});
}
});
TodoView = Backbone.View.extend({
tagName: "tr",
className: "todo-rec",
events: {
"click .edit": "editFields"
},
initialize: function() {
this.render();
this.updateContent();
},
render: function() {
var html = "<td><label id='task'class='edit tasklabel'></label><input id='edited-task'class='new-edit taskinput'style='display:none;' value=''></td><td><span id='due' class='edit duelabel'></span><input id='edited-due' class='new-edit dueinput' style='display:none;'value=''></td>"
this.$el.html(html);
return this;
},
editFields: function() {
console.log("todoView: editFields clicked");
},
updateContent: function() {
this.$el.find('.tasklabel').text(this.model.get('task'))
this.$el.find('.taskinput').val(this.model.get('task'))
this.$el.find('.duelabel').text(this.model.get('due'))
this.$el.find('.dueinput').val(this.model.get('due'))
}
});
var mainViewObj = new MainView();
<body>
<div id='content'>
Here is a sample div
<div id="content-body">
content to be changed
</div>
</div>
</body>
然而,我想知道你的最外层视图的html,以帮助你更好。请将它与小提琴的输出html进行比较,并让我知道。希望这能回答你的问题。
详细回答您的评论您可能想更改这段代码
//You might want to change this piece of code
var tbodyEl = $("<tbody />");
this.collection.each(function (item) {
var todoView = new TodoView({
model: item
});
tbodyEl.append(todoView.el);
});
this.$el.append(this.template({
project: projectName,
tbody: tbodyEl["0"].outerHTML
}));
你的tbodyEl基本上不指向任何东西,直到你渲染在添加
之前尝试执行此操作 this.$el.append(this.template({
project: projectName,
tbody: tbodyEl["0"].outerHTML
}));
// followed by
this.collection.each(function (item) {
var todoView = new TodoView({
model: item
});
tbodyEl.append(todoView.el);
});
相关文章:
- Odoo销售点如何访问模型并使用JS调用方法
- AngularJs 切换模板 URL 并访问模型数据
- 在ember.js中访问模型之外的计算属性
- 如何从单独的javascript文件访问模型属性?(MVC)
- 主干网需要.js访问模型
- 在 ng-admin 中访问模型值
- 主干 + 下划线:找不到模板变量.+ 如何正确访问模型属性
- 从另一个具有属于关系的模型访问模型属性 Ember.js
- 如何使用 javascript 变量访问模型属性
- Ember.js:控制器何时可以访问模型
- 从控制器外部访问模型数据's在AngularJS中的作用域
- 在回调中触发事件的访问模型
- 为什么backbone.js在访问模型时返回一个空数组
- 从控制器访问模型.Angular.js
- BackboneJS访问模型属性的问题
- Spotify应用程序预览API访问模型.球员属性
- Ember.js:如何在Javascript代码中访问模型的属性
- Javascript闭包:直接访问模型和使用变量的区别
- 访问模型中包含的数组中的字段
- 访问模型.Id在剃刀视图页面从javascript