在我们的租赁应用程序中,我们进行 API 调用来填充数组,从而触发 ngRepeat。这将创建一个 div 列表,显示有关出租特性的基本信息。
单击属性会展开 div,然后进行另一个 API 调用以使用租户列表填充内部 ngRepeat。其中一些特性列出了多达 100 名租户(包括过去和现在的租户)。租户 div 本身也是可扩展的,这揭示了大部分功能。您可以下载租赁协议(protocol)、查看历史记录等。所有这些功能都是由许多 ng-includes 组成的单个指令。
如果你还在关注,这里有一个外部 ngRepeat 和一个内部 ngRepeat,里面有一个巨大的指令。
<div ng-repeat="properties in property_collection track by property.ID>
*code removed*
<div ng-repeat="tenant in property_tenant_collection track by tenant.ID>
*...code here...*
<div tenant-menu></div>
当您展开属性列表时,会呈现指令 tenant-menu
以及它附带的所有 ngIninclude 和观察程序。他们只是还不可见。单击列表中的租户只会更改 div 的高度,从而显示内部菜单。
此 UI 设计方式对性能的影响绝对是可怕的。页面上有超过 15,000 名观察者关注您甚至看不到的元素。对一个租户采取行动会无缘无故地触发所有租户的摘要循环。检索必要数据只需不到一秒的时间,但呈现 60 名申请人的列表则需要近 20 秒。我已经完全删除了该指令(这意味着当您单击租户时不会发生任何事情),并且加载和渲染时间从 20 秒减少到 2-3 秒。
我不确定如何实现这一点,但是是否可以推迟附加此指令,直到单击租户为止?我不想单击租户 div 来更改高度并显示里面的内容,我想立即附加整个指令,然后扩展高度。理想情况下,当再次触发点击事件并且租户崩溃时,我还可以销毁任何观察者并自行清理。
哇。
编辑:臭名昭著的滑动指令粘贴在下面。我觉得里面绑定(bind)了一个点击事件很奇怪,但也许这是一个好的。 Angular 中的代码模式。我有预感,我也许能够利用编译、后链接和预链接功能以及已接受的答案。我认为我继承了一些遗留代码。
angular.module('jnjManagement.directives').directive('slideableTenant', function($compile, tenantService) {
return {
restrict: 'A',
link: function(scope, element, attrs) {
var targetX, contentX;
attrs.expanded = false;
element.bind('click', function() {
if (!targetX) targetX = document.querySelector(attrs.slideToggleTenant);
if (!contentX) contentX = targetX.querySelector('.slideable_tenant_content');
if (!attrs.expanded) {
contentX.style.border = '1px solid rgba(0,0,0,0)';
var y = contentX.clientHeight;
contentX.style.border = 0;
targetX.style.height = 'auto';
} else {
targetX.style.height = '0px';
}
attrs.expanded = !attrs.expanded;
});
}
};
});
最佳答案
理想情况下,您将拥有一个属性指令和一个租户指令,并且您实际上只会在单击扩展元素时加载它的内容。我会利用 Angular 的 $compile。
$scope.clickHandler = function(){
$('expanded-element').append($compile('<detail-directive></detail-directive')($scope));
};
当然,您也希望在元素折叠时清除它们,但听起来您对性能考虑因素有很好的把握。
关于javascript - 如何利用 AngularJS 指令的功能将渲染内容推迟到单击事件发生?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33025718/