2013-02-19 39 views
2

在我的真實網絡應用程序中,我有一個顯示文件夾的樹,在某些情況下,我在jQuery UI對話框中顯示此樹。我已經剝離出來盡我所能,把問題的例子在這個小提琴:這是因爲knockout.js或jQuery UI對話框的緩慢嗎?

http://jsfiddle.net/shopguy/gRbef/

如果單擊按鈕1,按下該鍵則對話框中的知名度。

如果您單擊按鈕2,它將切換內嵌(無對話框)列表可見性。

在Firefox中做我的大部分測試。點擊按鈕1大約需要1.5秒,顯示或隱藏(甚至隱藏很慢)。點擊按鈕2幾乎是瞬間的。

這是jQuery UI對話框的問題。它對每個hide/show上的DOM有很大的影響嗎?或者它只是一個問題,因爲我把它放在模板裏面? KO是否僅僅因爲它在模板中而重新創建了dom?

這兩種情況都使用模板,但對話框版本有一個額外的模板,用於對話框本身。他們都使用子文件夾的模板,儘管...因爲我不知道如何用KO做遞歸樹狀佈局。

這是從小提琴主HTML呈現W /樹佈局我的對話框:

<div data-bind="jqDialog: {autoOpen: false, modal: false, width: 350, height: 400, minWidth: 350, minHeight: 300 }, template: { name: 'folderDetailsTemplate' } , openDialog: dlg1"></div> 
<script type="text/html" id="folderDetailsTemplate"> 
List<br /> 
<ul data-bind="template: { name: 'tmpl1', foreach: folders}"></ul> 
</script> 
<script type="text/html" id="tmpl1"> 
<li> 
    <a data-bind="visible: expanded">-</a> 
    <a data-bind="visible: !expanded">+</a> 
    <a> 
    <span data-bind="text: name"></span> 
    </a> 
    <ul data-bind="template: { name: 'tmpl1', foreach: folders}"> 
    </ul> 
</li> 
</script> 

這是腳本:

ko.bindingHandlers.jqDialog = { 
     init: function (element, valueAccessor) { 
      var options = ko.utils.unwrapObservable(valueAccessor()); 
      $(element).dialog(options); 
     } 
    }; 

    ko.bindingHandlers.openDialog = { 
     update: function (element, valueAccessor) { 
      var value = ko.utils.unwrapObservable(valueAccessor()); 
      if (value) { 
       $(element).dialog("open"); 
      } else { 
       $(element).dialog("close"); 
      } 
     } 
    } 

    function Folder(i, l) { 
     this.name = "Test Folder " + i; 
     this.folders = ko.observableArray(); 
     this.expanded = true; 

     if (i < 4 && l < 4) { 
      var fs = new Array(); 
      for (var x = 0; x < 2; x++) { 
       var f = new Folder(x, l + 1); 
       fs.push(f); 
      } 
      this.folders(fs); 
     } 

    } 

    var vm = function() { 
     var self = this; 
     self.folders = ko.observableArray(); 
     var fs = new Array(); 
     for (var x = 0; x < 50; x++) { 
      var f = new Folder(x, 0); 
      fs.push(f); 
     } 
     self.folders(fs); 
     self.dlg1 = ko.observable(); 
     self.list1 = ko.observable(); 

     self.test1 = function() { 
      self.dlg1(!self.dlg1()); 
     } 

     self.test2 = function() { 
      self.list1(!self.list1()); 
     } 
    } 

    $(function() { 
     ko.applyBindings(new vm()); 
    }); 
+0

似乎並不如你在Firefox中,我幾乎報告慢。對話顯然比較慢,但並沒有那麼糟糕。 – 2013-02-19 01:18:12

+0

關於正確的聲音,我的電腦有點舊,仍然運行XP。 AMD雙核2.3ghz CPU,2GB RAM。儘管這是我的應用程序的一個關鍵領域,並且是KO/jQuery的新手,但是我想確保我從一個好的設計開始。 – eselk 2013-02-19 15:29:09

+0

刪除對話框的模板(移動div標籤內部的對話框,只有第二個模板,而不是第一個模板)確實使它超快,所以它與此有關。 jsFiddle現在有問題,所以無法更新以顯示我的更改示例。可能的話,可能會發佈一個可能的答案,但想要一個包含更多低級知識的答案,以幫助我和其他人瞭解此處的根本問題 – eselk 2013-02-19 16:10:35

回答

1

什麼使它慢就是openDialogtemplate綁定在同一元素的綁定字符串中分組在一起。因此,每次更新openDialog時,模板綁定也會更新並重新呈現您的模板。我想只是把模板嵌套評論像這樣綁定綁定:

<div data-bind="jqDialog: {autoOpen: false, modal: false, width: 350, height: 400, minWidth: 350, minHeight: 300 }, openDialog: dlg1"> 
     <!-- ko template: 'folderDetailsTemplate' --><!-- /ko --> 
</div> 

這是所有細節非常漂亮這裏:http://www.knockmeout.net/2012/06/knockoutjs-performance-gotcha-3-all-bindings.html

+0

完美,謝謝你的鏈接呢! – eselk 2013-03-09 02:51:29