2014-11-25 58 views
0

我正在使用chrome.bookmarks API以角度爲Chrome創建書籤管理器。角度性能和與深度嵌套集合的數據綁定

對於我的概念驗證,我的書籤頁是我的所有書籤的單個列表。我使用2個指令,兩個遍歷整個書籤集合,一個collection directive和一個member directive。我遇到性能問題,我正在尋找方向。

tl; dr: 模型更改將永久更新我的觀點,我做錯了什麼,以及我該如何做得更好?

下面是相關代碼:

app.controller('bookmarksController', ['$scope', 'ChromeBookmarks', function($scope, chromeBookmarks) { 
    chromeBookmarks.getBookmarks().then(function(bookmarkTree) { 
    $scope.bookmarks = bookmarkTree; 
    }); 
}); 

的index.html

<div ng-controller="bookmarkController"> 
    <collection collection="bookmarks"></collection> 
</div> 

collection.js

app.directive('collection', function($compile) { 
    return { 
    restrict: 'E', 
    scope: { 
     collection: '=', 
    }, 
    templateUrl: 'collection.html', 
    }; 
}); 

collection.html

<ul> 
    <member ng-repeat="member in collection" member="member"></member> 
</ul> 

member.js

app.directive('member', ['$compile', function($compile) { 
    return { 
    restrict: 'E', 
    scope: { 
     member: '=', 
    }, 
    templateUrl: 'member.html', 
    link: function(scope, element, attrs) { 
     if (scope.member.children) { 
     var collectionTemplate = '<collection collection="member.children"></collection>'; 
     var collection = angular.element(collectionTemplate); 
     element.append(collection); 
     $compile(collection)(scope); 
     }  
    } 
    }; 
}]); 

member.html

<li> 
    <bookmark ng-if="member.url" node="member"></bookmark> 
    <folder ng-if="!member.url" node="member"></folder> 
</li> 

bookmark.js

app.directive('bookmark', function() { 
    return { 
    restrict: 'E', 
    scope: { 
     node: '='   
    }, 
    templateUrl: 'bookmark.html' 
    }; 
}); 

bookmark.html

<div> 
    {{ node.title }} <button ng-click="open()">Live Site</button> 
</div> 

folder.js

app.directive('folder', function() { 
    return { 
    restrict: 'E', 
    scope: { 
     node: '=' 
    }, 
    templateUrl: 'folder.html' 
    }; 
}); 

folder.html

<div> {{ node.title }} </div> 

正如你可以在我的控制器上面看到的,我只有附着範圍一個模型:$scope.bookmarks。我只想加載一次這個變量。

頁面加載完成後,我想將偵聽器附加到chrome.bookmark events,這樣如果書籤發生更改,事件就會觸發,我只需更改受影響的書籤。

我目前使用的方法是使用一個函數,該函數將改變的書籤和遞歸地移動通過$scope.bookmarks,並用從chrome.bookmarks API獲得的更新版本替換書籤的父項。該功能基本上是這樣的:$scope.bookmarks[1].children[2] = updatedBookmark

我試着將偵聽器添加到我的頁面,但創建一個書籤和隨後更新的視圖需要3秒(壞),如果我書籤窗口中的每個選項卡,頁面凍結(更糟糕)。我確實擁有大約2k個書籤,但我仍然希望這能夠超越這個水平。

我的理解是,糟糕的角度性能與擁有大量觀察者有關,因爲$digest週期變得太大。 這是您認爲會導致我的表現問題嗎?

如果我只是想修改$scope.bookmarks模型來觸發更新視圖,我真的需要多少個觀察者?

我知道2路數據綁定是爲了保持模型和視圖同步,但我不禁想到,在我的情況下,我只想改變一點點數據(和變化基於書籤API事件,不一定是用戶輸入),2路數據綁定似乎是錯誤的,尤其是因爲$digest循環似乎檢查了太多的數據。

但是後來我確實需要視圖來正確鏡像模型數據。 如果我擺脫了雙向數據綁定,並且使用ngOnce進行一次綁定,我的模型的更改是否可以被渲染?

我剛剛遇到了角度的自然侷限性,需要使用不同的框架?

回答

1

Angular無法處理超過2000個手錶,有些瀏覽器可以做得更多,但這是一個不錯的上限。有兩種可能性進行緩慢更新:

1)您正在使用Angular生命週期調用的API?如果是這樣,請確保您執行一個作用域$ apply()。 2)你有太多的手錶。有代碼片段,你可以發現你在控制檯中運行,會反彈手錶的數量如果它們很高,那麼考慮緩衝你的視圖,以便只有你看到的是綁定的,github.com/EnzeyNet/VirtualScroll。

+0

我已經告訴視圖使用範圍進行更新$ apply,這就是觸發摘要循環並放慢速度的一切 – markain 2014-11-25 17:54:39

+0

您註冊了多少手錶?在這裏嘗試一個腳本:http://stackoverflow.com/questions/18499909/how-to-count-total-number-of-watches-on-a-page – Enzey 2014-11-25 20:16:27