我有以下Backbone.js视图,它工作正常。我有一个DIV id='edit-div'
,我将视图渲染成它:
var BookView = Backbone.View.extend({
initialize: function(){
console.log('BookView created');
},
events: {
"click a.rm": "rm_clicked",
"click a.vi": "vi_clicked"
},
vi_clicked: function(e){
var bv = new EditBookView({model: this.model, el: $(book_edit_el)});
bv.render();
},
以下是视图代码:
var EditBookView = Backbone.View.extend({
model: Book,
tagName: 'div',
className: 'edit-book',
initialize: function(){
console.log('Editing book view created');
},
events: {
"click a.sed": "sed_clicked",
},
sed_clicked: function(e){
var newval = $("#bookname").val();
this.model.set('BookName', newval);
this.model.save();
this.remove();
},
render: function(){
console.log('Rendering EditBookView');
this.$el.append('<input id="bookname" type="text" value="' + this.model.get('BookName') + '"/><a class="sed" href="javascript:;">Save</a>');
return this;
}
});
现在,我单击“保存”,调用sed_clicked
方法并通过REST服务更新我的书,没问题。
问题是,我的edit-div
消失了,下次点击编辑时,我的编辑视图无法渲染,因为它没有容器。如果我不删除,当我添加另一个视图时,保存点击的处理程序将保持注册状态。我无法找到一个很好的例子来摧毁编辑器,但是我可以在我查看的列表中创建另一个编辑器。
任何想法
编辑说:
我正在寻找的模式是非常基本的,我有一个模型集的表视图,带有删除链接(工作正常)和编辑链接。编辑链接呈现所选元素的输入(再次,工作正常)并检测保存链接单击以更新模型(也正常工作)。我无法弄清楚如何在更新后删除表单,然后在点击后显示下一个表单。
我最后删除了div,当我调用remove()时,我将它附加到div上,或者我只是隐藏()代码或替换它不会解除调用更新的事件监听器,第二次编辑时更新2次项目,第三次3次,依此类推。
答案 0 :(得分:1)
您的问题是remove
内的sed_clicked
来电:
sed_clicked: function(e){
var newval = $("#bookname").val();
this.model.set('BookName', newval);
this.model.save();
this.remove(); // <--------------------------
}
您在创建该视图时会为该视图提供现有的el
:
var bv = new EditBookView({model: this.model, el: $(book_edit_el)});
// -------------------------------------------^^^^^^^^^^^^^^^^^^^
和remove
确实:
删除
view.remove()
从DOM中删除视图及其
el
,并调用 stopListening 以删除视图 listenTo 的任何绑定事件。
因此,当您在视图上调用remove
时,它会从DOM中删除其el
。您还可以查看the source以查看正在进行的操作:
// Remove this view by taking the element out of the DOM, and removing any
// applicable Backbone.Events listeners.
remove: function() {
this._removeElement();
this.stopListening();
return this;
},
// Remove this view's element from the document and all event listeners
// attached to it. Exposed for subclasses using an alternative DOM
// manipulation API.
_removeElement: function() {
this.$el.remove();
},
默认remove
实施在您正在查看时使用的el
没有创建,但您可以提供自己的remove
remove: function() {
this.undelegateEvents();
this.$el.empty();
this.stopListening();
return this;
}
。 1}}来解释:
el
调用empty
代替remove
会删除el
的内容(包括事件处理程序等),同时保留元素不变,undelegateEvents
调用将删除Backbone附加到视图el
。
更好的方法(IMO)是不将el
传递给视图;相反,让视图创建自己的el
并让调用者将remove
放在某个容器中。如果您这样做,那么标准connectionString="Data Source=PC210090\\SQLEXPRESS;
就足够了,您可以减少泄漏和事件的问题。
答案 1 :(得分:0)
在没有看到HTML标记的情况下完全理解您的问题有点困难,但是,我认为解决方案是将EditBookView渲染到BookView中的容器元素中:
Sub SaveWorkbook()
Dim C As Range
Dim lastC As Long
Dim lastRow As Long
Dim eRow As Long
Dim w1 As Workbook
Dim w2 As Workbook
Dim rng As Range
Dim v As Variant
Application.ScreenUpdating = False
'Clear workers on shift
'-------------------------------------------------------------------------
ActiveWorkbook.SaveAs Filename:="C:\Users\sreilly\Documents\test\" & Worksheets("Cover").Range("B5").Text & ".xlsm"
Sheets("Cover").Activate
lastC = Cells(Rows.Count, "C").End(xlUp).Row + 16
With Range("B13:F50")
.ClearContents
End With
'Open Mastersheet and define empty row in Downtimes
'-------------------------------------------------------------------------
Application.Workbooks.Open ("C:\Users\sreilly\Documents\test\ShiftReportMaster.xlsx")
Set w1 = Workbooks(Worksheets("Cover").Range("B5").Text & ".xlsm")
Set w2 = Workbooks("ShiftReportMaster.xlsx")
lastRow = Workbooks(w1).Worksheets("Downtime").Cells(Rows.Count, "A").End(xlUp).Row
eRow = Workbooks(w2).Worksheets("Downtimes").Cells(Rows.Count, "A").End(xlUp).Row
'For all Downtimes in Daily Shift Report find if they are new or update existing in mastersheet
'----------------------------------------------------------------------------------------------
For n = 5 To lastRow
v = Application.Match(Workbooks(w1).Worksheets("Downtime").Cells(n, 1), Workbooks(w2).Worksheets("Downtimes").Columns("A"), 0)
eRow = eRow + 1
If IsNumeric(v) Then
Workbooks(w2).Worksheets("Downtimes").Range("cells(v,2):cells(v,15)").Value = Workbooks(w1).Worksheets("Downtime").Range("cells(v,2):cells(v,15)").Value
Else
Workbooks(w2).Worksheets("Downtimes").Range("cells(eRow,1):cells(eRow,15)").Value = Workbooks(w1).Worksheets("Downtime").Range("cells(v,1):cells(v,15)").Value
End If
Next n*
'Save and close mastersheet with changes and clear all information to make new template for next shift
'------------------------------------------------------------------------------------------------------
Workbooks("ShiftReportMaster.xlsx").Close savechanges:=True
Sheets("downtime").Range("A1:O100").ClearContents 'clear downtimes
Sheets("downtime").Range("Q5:T100").ClearContents 'clear delays
Sheets("workorder").Range("A8:BZ100").ClearContents 'clear workorder information
Sheets("Time confirmations").Range("A2:L100").ClearContents 'clear time confirmation information
Sheets("cover").Range("E5:E7").ClearContents 'clear Crew, Supervisor and Coordinator
Sheets("Cover").Activate
If Range("E4").Value = "DS" Then
Range("E4").Value = "NS"
Else
Range("E4").Value = "DS"
Range("F3").Value = Range("F3").Value + 1
End If
'If next shifts report doesnt exist in folder already, create it other wise skip this step
'------------------------------------------------------------------------------------------
If Dir("C:\Users\sreilly\Documents\test\" & Worksheets("Cover").Range("B5").Text & ".xlsm") = "" Then
ActiveWorkbook.Close savechanges:=True, Filename:="C:\Users\sreilly\Documents\test\" & Worksheets("Cover").Range("B5").Text & ".xlsm", RouteWorkbook:=False
End If
Application.ScreenUpdating = True
End Sub