Backbone Edit查看,销毁并重新显示问题

时间:2015-10-07 22:37:08

标签: javascript jquery backbone.js

我有以下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次,依此类推。

2 个答案:

答案 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