gpt4 book ai didi

javascript - 嵌套ng-repeat导致浏览器卡顿如何处理

转载 作者:可可西里 更新时间:2023-11-01 01:43:46 28 4
gpt4 key购买 nike

我创建了一个可能有 1 - 5000 个项目的嵌套树,我能够让它工作,但它在显示树之前卡住了我的浏览器\加载微调器几秒钟。

我怎样才能使它流畅以使浏览器永远不会卡住?

我怎么知道 angularjs 何时完成创建或渲染或计算(不确定正确的词)整个列表,以便我可以删除加载微调器,如您所见范围。$last 不起作用因为我们已经嵌套了 ng-repeat 并且对于 scope.$parent.$last

这是我创建的 plunker,但带有演示数据 -

http://plnkr.co/edit/GSZEpHjt5YVxqpg386k5?p=preview

示例数据集 - http://pastebin.com/YggqE2MK

在这个例子中并不算太糟糕,但在我的 OWN 设置和所有其他组件中,我的浏览器有时会卡住大约 4000 个项目超过 10 秒。

我已经考虑过的

  • 使用了 bindonce.js 库,但不太成功
  • 再次使用“::”单一绑定(bind)但没有成功
  • 仅在用户展开类别时加载第一级然后渲染下一级,但我的树可能非常随机,也许我只有 1 个单根节点和 100 多个子节点
  • 分页不适合场景

HTML

  <script type="text/ng-template" id="tree_item">
<div ng-init="category.expanded=true">
<div ng-class="{'selected': category.ID==selectedCategoryID}">
<div class="icon icon16" ng-if="category.Children.length>0" ng-click="$parent.category.expanded=!$parent.category.expanded" ng-class="$parent.category.expanded?'col':'exp'"></div>
<div class="icon icon-category" ng-class="'icon-category-'+category.TypeType" ng-style="{'border-color':category.Colour}" ng-attr-title="{{category.Status?Res['wpOPT_Status'+category.Status]:''}}"></div>
<a ng-href="#id={{category.ID}}" ng-class="{'pending-text': category.PendingChange}">{{category.Name}}</a>
</div>
<ul class="emlist" ng-show="category.expanded">
<li ng-repeat="category in category.Children | orderBy:'Name'" ng-include="'tree_item'" ng-class="{'selected': category.ID==selectedCategoryID}" e2-tree-item is-selected="category.ID==selectedCategoryID">
</li>
</ul>
</div>
</script>

<div id="CategoryListContainer" class="dragmenu-container initial-el-height">
<div class="spinner" data-ng-show="status=='loading'"></div>
<ul id="CategoryList" class="dragmenu-list ng-cloak" ng-show="status=='loaded'">
<li ng-repeat="category in tree | orderBy:'Name'" ng-include="'tree_item'" e2-tree-item is-selected="category.ID==selectedCategoryID"></li>
</ul>
</div>

JS

var app = angular.module('recursionDemo', []);

app.controller("TreeController", function($scope, $timeout) {
$scope.status = "loading";

$timeout(function() {
var result = {
"GetCategoryTreeResult": [{ // too big data set so I pasted it here http://pastebin.com/YggqE2MK }];
$scope.tree = result.GetCategoryTreeResult;

$scope.status = "loaded";
}, 3000);
});

app.directive('e2TreeItem', function($timeout) {
function link(scope, element, ngModel) {
scope.$watch('isSelected', function(oldVal, newVal) {
if (scope.isSelected === true) {
element.parentsUntil('#CategoryListContainer', 'li').each(function(index, item) {
angular.element(item).scope().category.expanded = true;
});
}
});

// not working
//if (scope.$parent.$last) {
// console.log("last has been caught");
// var appElement = document.querySelector('[ng-app=recursionDemo]');
// angular.element(appElement).scope().status = "loaded";
//}
}
return {
link: link,
scope: {
isSelected: '=?'
}
};
});

最佳答案

更新:

演示:http://plnkr.co/edit/bHMIU8Mx5grht9nod1CW?p=preview

您可以通过更改 app.js 的 L10901 来顺利加载数据,如下所示。但是你应该注意到,如果你仍然想按名称排序,并希望它稳定,你应该只对源数据进行排序,而不是使用“order by”进行 Angular 排序。 (你想要一些代码来对源数据进行排序吗?)

    function getDataGradually(data, childKey, gap, count, updateCb, finishCb) {
const lastPositon = [];
const linearData = [];
const ret = [];


function getLinearData(arr, position) {
arr.forEach(function (obj, index) {
const pos = position.concat([index]);
if (obj[childKey] && obj[childKey].length) {
var children = obj[childKey];
obj[childKey] = [];
linearData.push({
obj,
pos
});
getLinearData(children, pos);
} else {
linearData.push({
obj,
pos
});
}
});
}
getLinearData(data, []);

function insertData({
obj,
pos
}) {

let target = ret;
pos.forEach(function (i, index) {


if (index === pos.length - 1) {
target[i] = obj;

} else {
target = target[i][childKey];
}
});

}
let handled = 0;

function doInsert() {
let start = handled;
let end;
if (handled + count > linearData.length) {
end = linearData.length;
} else {
end = handled + count;
}
for (let i = start; i < end; i++) {
insertData(linearData[i]);
}
handled += count;
if (handled < linearData.length) {
setTimeout(function () {
doInsert();
updateCb && updateCb();
}, gap);
} else {
finishCb && finishCb();
}
}
doInsert();



return ret;
}

$scope.tree = getDataGradually(result.GetCategoryTreeResult, "Children", 0, 30, function () {
$scope.$digest();
}, function () {
//finished
});
//$scope.tree = result.GetCategoryTreeResult;
$scope.status = "loaded";
}, 3000);

旧答案:

您可以使用$timeout 获取渲染时间。尝试更改 app.js 的 L10901,如下所示。

        $scope.tree = result.GetCategoryTreeResult;
console.time("A")
$timeout(function(){
console.timeEnd("A");
});
$scope.status = "loaded";
}, 3000);

顺便说一句,我的电脑上出现“1931.881ms”。

关于javascript - 嵌套ng-repeat导致浏览器卡顿如何处理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42552198/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com