2016-08-03 36 views
0

Ich erstelle Registerkarten, wenn auf eine Verknüpfung in einer Strukturansicht geklickt wird. Innerhalb der Registerkarte werden zwei weitere Registerkarten erstellt, in denen Textfelder enthalten sind, die in CodeMirror umgewandelt werden. Ich habe an vielen Dingen hängengeblieben, wenn es darum geht, die CodeMirror-Instanz zu erstellen, und normalerweise waren meine Probleme mit dem Ereignis .refresh().jQuery, Bootstrap-Registerkarten und CodeMirror.refresh()

Codemirror wurde nicht vollständig in das Register geladen, die nicht aktiv ist, so habe ich einige Änderungen, wenn es darum geht, die Instanzen zu erstellen und ich sammle sie alle in Arrays, die ich später in Codeschleife durch .refresh(), so dass die Codemirror-Editoren zu verwenden voll laden.

Bevor ich das gemacht habe, wurde CodeMirror zu allen Textfeldern in allen Tabs hinzugefügt, die ich beim Klicken erstellt habe, aber ich habe immer alle CodeMirror-Instanzen aktualisiert, nicht nur die auf der neuen Registerkarte. Dies führte dazu, dass Werte, die in einer anderen Registerkarte eingegeben wurden, gelöscht wurden.

Mit der neuen Änderung aktualisiere ich nur die aktuellen CodeMirror-Instanzen, die in der neuen Registerkarte erstellt werden. Aber jetzt mit dieser Änderung verschwindet CodeMirror in allen älteren Tabs, die noch geöffnet sind (abgesehen davon, dass die Tabs geschlossen werden können). So, jetzt frage ich mich, wird CodeMirror.refresh() die ganze Seite aktualisieren?

Unten ist ein Teil meines Codes, der Teil, der die CodeMirror-Instanzen erstellt. Ich glaube nicht, der Code, der die Registerkarten etwas mit diesem Dysfunktionalität zu tun hat, schafft:

/* Codemirror Fügen Sie alle Textfelder zu konvertieren, muss Timeout bis alle dom Elemente */

setTimeout(function() { 
    var textAreaId = 0; 
    $(".AI-textarea").each(function() { 
     $(this).attr("id", "text" + textAreaId); 
     ++textAreaId; 
    }); 

    var queryArr = []; 
    var dimensionArr = []; 

    var queryBuilder = $(tabPanelDiv).find(".QueryBuilder"); 
    queryBuilder.each(function (index, el) { 
     var editorQuery = CodeMirror.fromTextArea(el, { 
      lineNumbers: true, 
      tabMode: "indent", 
      mode: "text/x-sql", 
      theme: "eclipse" 
     }); 
     queryArr.push(editorQuery); 
    }); 

    var dimensionBuilder = $(tabPanelDiv).find(".DimensionBuilder"); 
    dimensionBuilder.each(function (index, el) { 
     var editorQuery = CodeMirror.fromTextArea(el, { 
      lineNumbers: true, 
      tabMode: "indent", 
      mode: "text/x-sql", 
      theme: "eclipse" 
     }); 
     dimensionArr.push(editorQuery); 
    }); 

    for (var i = 0; i < queryArr.length; i++) { 
     queryArr[i].refresh(); 
    } 

    for (var a = 0; a < dimensionArr.length; a++) { 
     dimensionArr[a].refresh(); 
    } 

}, 100); 
geladen werden

Ich muss den Code in einer setTimeout-Funktion haben, um darauf zu warten, dass die Textareas erstellt werden. Die Funktion befindet sich in einem On-Click-Ereignis.

Kann jemand darauf hinweisen, was den CodeMirror aus dem Dom in älteren Tabs verschwinden lassen könnte? Ist es vielleicht das CodeMirror.refresh() Ereignis oder macht ein Klickereignis etwas, was mir nicht bekannt ist? Geht die letzte CodeMirror-Instanz verloren, während ein neuer Tab erstellt wird?

Im Folgenden finden Sie zwei Screenshots von Tabs, das erste zeigt, wie ein brandneuer Tab aussieht. Die zweite zeigt, wie die ältere Registerkarte, die gleich aussehen sollte, aussieht.

enter image description here

enter image description here

EDIT

Hier ist das Click-Ereignis ganz, wenn das hilft, vielleicht etwas früher im Code ist dies verursacht? Ich entschuldige mich für das Mischen von Javascript und jQuery, werde wahrscheinlich etwas neu schreiben müssen.

$(".treeviewLinks").click(function (e) { 
     e.preventDefault(); 
     var targetElement = e.target || e.srcElement; 

     /*** Create everything for the upper tabs that open when tree view link is clicked ***/ 

     if ($(".tabHelper").find("#upperTab").length == 0) { 
      var ul = document.createElement("ul"); 
      ul.className = "nav nav-tabs"; 
      ul.id = "upperTab"; 
      ul.setAttribute("role", "tablist"); 
      $(".tabHelper").append(ul); 
     } 

     var ul = $("#upperTab"); 
     var id = $('#upperTab li').size() + 1; 

     var li = document.createElement("li"); 
     var a = document.createElement("a"); 
     var span = document.createElement("span"); 

     li.setAttribute("role", "presentation"); 
     a.href = "#" + id; 
     a.setAttribute("aria-controls", id); 
     a.setAttribute("role", "tab"); 
     a.setAttribute("data-toggle", "tab"); 
     span.className = "glyphicon glyphicon-remove pull-right exit"; 
     a.innerHTML = targetElement.innerHTML; 

     if ($(".tabHelper").find(".tab-content").length == 0) { 
      var tabContentDiv = document.createElement("div"); 
      tabContentDiv.className = "tab-content"; 
     } 

     $(".tabHelper").append(tabContentDiv); 

     var tabContentDiv = $(".tabHelper").find(".tab-content").first(); 
     var tabPanelDiv = document.createElement("div"); 

     tabPanelDiv.className = "tab-pane" 
     tabPanelDiv.id = id; 
     tabPanelDiv.setAttribute("role", "tabpanel"); 

     ul.append(li); 
     li.appendChild(a); 
     a.appendChild(span); 
     tabContentDiv.append(tabPanelDiv); 

     var upperTab = document.getElementById("upperTab"); 
     var tabContent = document.getElementsByClassName("tab-content")[0]; 
     var cId = $(tabContent).size() + 1; 

     if (id == 1) { 
      var tmpLi = upperTab.firstChild; 
      tmpLi.className = "active"; 
     } 
     else if (id > 1) { 
      $(li).siblings().removeClass("active"); 
      li.className = "active"; 
     } 

     if (cId == 1) { 
      var tmpTabPane = tabContent.firstChild; 
      tmpTabPane.className += " active"; 
     } 
     else if (cId > 1) { 
      $(tabPanelDiv).siblings().removeClass("active"); 
      tabPanelDiv.className += " active"; 
     } 

     /*** Create ul for nav-tabs and tab-content for query and dimension builder tabs ***/ 

     var qdUl = document.createElement("ul"); 
     qdUl.className = "nav nav-tabs query-dimension-tabs"; 
     qdUl.setAttribute("role", "tablist"); 

     var qdDiv = document.createElement("div"); 
     qdDiv.className = "tab-content query-dimsension-tabs-content"; 

     for (var i = 0; i < tabContent.childNodes.length; i++) { 
      var item = $(tabContent.childNodes[i]); 

      if (item.children().length < 1) { 
       item.append(qdUl); 
       item.append(qdDiv); 
      } 
     } 

     /*** Create li in nav-tabs and tab-panel in tab-content for query and dimension builder tabs ***/ 

     var qLi = document.createElement("li"); 
     var dLi = document.createElement("li"); 
     qLi.setAttribute("role", "presentation"); 
     qLi.className = "active"; 
     dLi.setAttribute("role", "presentation"); 

     var navTabs = $(".query-dimension-tabs"); 

     var qA = document.createElement("a"); 
     var dA = document.createElement("a"); 
     qA.setAttribute("role", "tab"); 
     qA.setAttribute("data-toggle", "tab"); 
     qA.innerHTML = "Query Builder"; 
     dA.setAttribute("role", "tab"); 
     dA.setAttribute("data-toggle", "tab"); 
     dA.innerHTML = "Dimension Builder"; 

     for (var i = 0; i < navTabs.length; i++) { 
      var item = $(navTabs[i]); 

      if (item.children().length < 1) { 
       item.append(qLi); 
       item.append(dLi); 
       qLi.appendChild(qA); 
       dLi.appendChild(dA); 
      } 
     } 

     var qdId = 0; 
     $(".query-dimension-tabs").each(function() { 
      $(this).find("a").each(function() { 
       $(this).attr("href", "#tab" + qdId); 
       $(this).attr("aria-controls", "tab" + qdId); 
       ++qdId; 
      }); 
     }); 

     var tabPane1 = document.createElement("div"); 
     var tabPane2 = document.createElement("div"); 
     tabPane1.className = "tab-pane active"; 
     tabPane1.setAttribute("role", "tabpanel"); 
     tabPane2.className = "tab-pane"; 
     tabPane2.setAttribute("role", "tabpanel"); 

     $(".tab-content:not(:first)").each(function() { 
      $(this).append(tabPane1); 
      $(this).append(tabPane2); 
     }); 

     var pId = 0; 
     $(".query-dimsension-tabs-content").each(function() { 
      $(this).find(".tab-pane").each(function() { 
       $(this).attr("id", "tab" + pId); 
       ++pId; 
      }); 

      if (!($.contains($(this), "form"))) { 
       var firstPane = $($(this).children()[0]); 
       var secondPane = $($(this).children()[1]); 
       firstPane.load("/Webfront/QueryBuilder"); 
       secondPane.load("/Webfront/DimensionBuilder"); 
      }   
     }); 

     //var url = '@Url.Action("QueryDimensionTab", "Webfront")'; 

     /*** Add CodeMirror to convert all textboxes, needs timeout until all dom elements are loaded ***/ 

     setTimeout(function() { 
      var textAreaId = 0; 
      $(".AI-textarea").each(function() { 
       $(this).attr("id", "text" + textAreaId); 
       ++textAreaId; 
      }); 

      var queryArr = []; 
      var dimensionArr = []; 

      var queryBuilder = $(tabPanelDiv).find(".QueryBuilder"); 
      queryBuilder.each(function (index, el) { 
       var editorQuery = CodeMirror.fromTextArea(el, { 
        lineNumbers: true, 
        tabMode: "indent", 
        mode: "text/x-sql", 
        theme: "eclipse" 
       }); 
       queryArr.push(editorQuery); 
      }); 

      var dimensionBuilder = $(tabPanelDiv).find(".DimensionBuilder"); 
      dimensionBuilder.each(function (index, el) { 
       var editorQuery = CodeMirror.fromTextArea(el, { 
        lineNumbers: true, 
        tabMode: "indent", 
        mode: "text/x-sql", 
        theme: "eclipse" 
       }); 
       dimensionArr.push(editorQuery); 
      }); 

      for (var i = 0; i < queryArr.length; i++) { 
       queryArr[i].refresh(); 
      } 

      for (var a = 0; a < dimensionArr.length; a++) { 
       dimensionArr[a].refresh(); 
      } 

     }, 100); 
    }); 

Antwort

0

Ich fand was CodeMirror ältere Instanzen zu verschwinden verursacht. Es war, weil ich die Formulare innerhalb einer jQuery .each() geladen habe, die alle Divs durchläuft, die diese Formulare haben. Ich habe die Ladung nach draußen bewegt, und das hat sie repariert.

Alter Code:

var pId = 0; 
    $(".query-dimsension-tabs-content").each(function() { 
     $(this).find(".tab-pane").each(function() { 
      $(this).attr("id", "tab" + pId); 
      ++pId; 
     }); 

     if (!($.contains($(this), "form"))) { 
      var firstPane = $($(this).children()[0]); 
      var secondPane = $($(this).children()[1]); 
      firstPane.load("/Webfront/QueryBuilder"); 
      secondPane.load("/Webfront/DimensionBuilder"); 
     }   
    }); 

Neuer Code:

var pId = 0; 
    $(".query-dimsension-tabs-content").each(function() { 
     $(this).find(".tab-pane").each(function() { 
      $(this).attr("id", "tab" + pId); 
      ++pId; 
     });   
    }); 

    var formToLoad = $($(tabPanelDiv).children()[1]); 
    var firstPane = $($(formToLoad)[0].firstChild); 
    var secondPane = $($(formToLoad)[0].lastChild); 
    firstPane.load("/Webfront/QueryBuilder"); 
    secondPane.load("/Webfront/DimensionBuilder"); 

Wenn jemand Empfehlung oder Ideen hat, wie ich diese Teilansichten dynamisch in jQuery in einer anderen Art und Weise laden konnte die geschätzt werden würde. Ich denke, das ist wahrscheinlich nicht der beste Weg.