我创建了一个可能有 1 - 5000 个项目的嵌套树,我能够让它工作,但它在显示树之前卡住了我的浏览器\加载微调器几秒钟。
我怎样才能使它流畅以使浏览器永远不会卡住?
我怎么知道 angularjs 何时完成创建或渲染或计算(不确定正确的词)整个列表,以便我可以删除加载微调器,如您所见范围。$last 不起作用因为我们已经嵌套了 ng-repeat 并且对于 scope.$parent.$last
这是我创建的 plunker,但带有演示数据 -
http://plnkr.co/edit/GSZEpHjt5YVxqpg386k5?p=preview
示例数据集 - http://pastebin.com/YggqE2MK
在这个例子中并不算太糟糕,但在我的 OWN 设置和所有其他组件中,我的浏览器有时会卡住大约 4000 个项目超过 10 秒。
我已经考虑过的
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/
我得到了一个包含嵌套链接的表单。编辑时链接字段为空的问题。这是我的表格:Editingkategori{:action=>'update',:id=>@konkurrancer.id})do|f|%>'Trackingurl',:style=>'width:500;'%>'Editkonkurrence'%>|我的konkurrencer模型:has_one:link我的链接模型:classLink我的konkurrancer编辑操作:defedit@konkurrancer=Konkurrancer.find(params[:id])@konkurrancer.link_attrib
这道题是thisquestion的逆题.给定一个散列,每个键都有一个数组,例如{[:a,:b,:c]=>1,[:a,:b,:d]=>2,[:a,:e]=>3,[:f]=>4,}将其转换为嵌套哈希的最佳方法是什么{:a=>{:b=>{:c=>1,:d=>2},:e=>3,},:f=>4,} 最佳答案 这是一个迭代的解决方案,递归的解决方案留给读者作为练习:defconvert(h={})ret={}h.eachdo|k,v|node=retk[0..-2].each{|x|node[x]||={};node=node[x]}node[
我在理解Enumerator.new方法的工作原理时遇到了一些困难。假设文档中的示例:fib=Enumerator.newdo|y|a=b=1loopdoy[1,1,2,3,5,8,13,21,34,55]循环中断条件在哪里,它如何知道循环应该迭代多少次(因为它没有任何明确的中断条件并且看起来像无限循环)? 最佳答案 Enumerator使用Fibers在内部。您的示例等效于:require'fiber'fiber=Fiber.newdoa=b=1loopdoFiber.yieldaa,b=b,a+bendend10.times.m
下面例子中的Nested和Child有什么区别?是否只是同一事物的不同语法?classParentclassNested...endendclassChild 最佳答案 不,它们是不同的。嵌套:Computer之外的“Processor”类只能作为Computer::Processor访问。嵌套为内部类(namespace)提供上下文。对于ruby解释器Computer和Computer::Processor只是两个独立的类。classComputerclassProcessor#Tocreateanobjectforthisc
我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的
我有一个名为posts的模型,它有很多附件。附件模型使用回形针。我制作了一个用于创建附件的独立模型,效果很好,这是此处说明的View(https://github.com/thoughtbot/paperclip):@attachment,:html=>{:multipart=>true}do|form|%>posts中的嵌套表单如下所示:prohibitedthispostfrombeingsaved:@attachment,:html=>{:multipart=>true}do|at_form|%>附件记录已创建,但它是空的。文件未上传。同时,帖子已成功创建...有什么想法吗?
我真的为这个而疯狂。我一直在搜索答案并尝试我找到的所有内容,包括相关问题和stackoverflow上的答案,但仍然无法正常工作。我正在使用嵌套资源,但无法使表单正常工作。我总是遇到错误,例如没有路线匹配[PUT]"/galleries/1/photos"表格在这里:/galleries/1/photos/1/edit路线.rbresources:galleriesdoresources:photosendresources:galleriesresources:photos照片Controller.rbdefnew@gallery=Gallery.find(params[:galle
我正在我的Rails项目中安装Grape以构建RESTfulAPI。现在一些端点的操作需要身份验证,而另一些则不需要身份验证。例如,我有users端点,看起来像这样:moduleBackendmoduleV1classUsers现在如您所见,除了password/forget之外的所有操作都需要用户登录/验证。创建一个新的端点也没有意义,比如passwords并且只是删除password/forget从逻辑上讲,这个端点应该与用户资源。问题是Grapebefore过滤器没有像except,only这样的选项,我可以在其中说对某些操作应用过滤器。您通常如何干净利落地处理这种情况?
我需要根据字符串路径的长度将字符串路径数组转换为符号、哈希和数组的数组给定以下数组:array=["info","services","about/company","about/history/part1","about/history/part2"]我想生成以下输出,对不同级别进行分组,根据级别的结构混合使用符号和对象。产生以下输出:[:info,:services,about:[:company,history:[:part1,:part2]]]#altsyntax[:info,:services,{:about=>[:company,{:history=>[:part1,:pa
我目前正在用Ruby编写一个项目,它使用ActiveRecordgem进行数据库交互,我正在尝试使用ActiveRecord::Base.logger记录所有数据库事件具有以下代码的属性ActiveRecord::Base.logger=Logger.new(File.open('logs/database.log','a'))这适用于迁移等(出于某种原因似乎需要启用日志记录,因为它在禁用时会出现NilClass错误)但是当我尝试运行包含调用ActiveRecord对象的线程守护程序的项目时脚本失败并出现以下错误/System/Library/Frameworks/Ruby.frame