我正在使用chrome.bookmarks API为Chrome制作一个书签管理器。
对于我的概念证明,我的书签页面是我所有书签的单个列表。我正在使用 2 个指令,两个遍历我的书签的整个集合,一个collection directive
和一个member directive
。我遇到了性能问题,我正在寻找方向。
博士: 模型更改需要永远更新我的观点,我做错了什么,我怎样才能做得更好?
以下是相关代码:
app.controller('bookmarksController', ['$scope', 'ChromeBookmarks', function($scope, chromeBookmarks) {
chromeBookmarks.getBookmarks().then(function(bookmarkTree) {
$scope.bookmarks = bookmarkTree;
});
});
索引.html
<div ng-controller="bookmarkController">
<collection collection="bookmarks"></collection>
</div>
收藏.js
app.directive('collection', function($compile) {
return {
restrict: 'E',
scope: {
collection: '=',
},
templateUrl: 'collection.html',
};
});
收藏.html
<ul>
<member ng-repeat="member in collection" member="member"></member>
</ul>
成员.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);
}
}
};
}]);
成员.html
<li>
<bookmark ng-if="member.url" node="member"></bookmark>
<folder ng-if="!member.url" node="member"></folder>
</li>
书签.js
app.directive('bookmark', function() {
return {
restrict: 'E',
scope: {
node: '='
},
templateUrl: 'bookmark.html'
};
});
书签.html
<div>
{{ node.title }} <button ng-click="open()">Live Site</button>
</div>
文件夹.js
app.directive('folder', function() {
return {
restrict: 'E',
scope: {
node: '='
},
templateUrl: 'folder.html'
};
});
文件夹.html
<div> {{ node.title }} </div>
正如您在上面的控制器中看到的那样,我只有一个模型附加到示波器:$scope.bookmarks
.我只想加载这个变量一次。
页面加载后,我想将侦听器附加到 chrome.bookmark 事件,以便在书签更改时触发事件,我只需要更改受影响的书签。
我目前执行此操作的方法是使用一个函数,该函数获取更改的书签并递归地在$scope.bookmarks
中移动,并将书签的父项替换为我从chrome.bookmarks API获得的更新版本。该函数基本上执行以下操作: $scope.bookmarks[1].children[2] = updatedBookmark
我尝试将侦听器添加到我的页面,但是创建书签并随后更新视图需要 3 秒(不好),如果我为窗口中的每个选项卡添加书签,页面会冻结(更糟)。我确实有大约 2k 个书签,但我仍然希望它的性能超出该级别。
我的理解是,糟糕的角度表现与拥有大量的观察者有关,因为$digest
周期变得太大。这是您认为导致我性能问题的原因吗?
如果我只想修改$scope.bookmarks
模型以触发视图更新,我真正需要多少个观察者?
我知道 2 路数据绑定旨在保持模型和视图同步,但我不禁想到,就我而言,我只想更改一点数据(并且更改基于书签 API 事件,不一定是用户输入),2 路数据绑定似乎是错误的, 特别是因为$digest
循环似乎检查了如此多的数据。
但话又说回来,我确实需要视图来正确镜像模型数据。如果我摆脱了 2 路数据绑定,并使用 ngOnce
进行一次性绑定,是否可以呈现对模型的更改?
我是否只是遇到了角度的自然限制并需要使用不同的框架?
Angular 不能处理超过 ~2000 个手表,一些浏览器可以做更多,但这是一个很好的上限。缓慢更新有两种可能性:
1) 你在 Angular 生命周期中调用的 API 是否在 Angular 生命周期内?如果是这样,请确保执行 scope.$apply()。2)你的手表太多了。您可以在控制台中找到一些代码片段,这些代码片段将吐回监视的数量 如果它们很高,请考虑缓冲您的视图,以便只有您看到的内容被绑定,github.com/EnzeyNet/VirtualScroll。