javascript - 如何利用 AngularJS 指令的功能将渲染内容推迟到单击事件发生?

标签 javascript angularjs

在我们的租赁应用程序中,我们进行 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/

相关文章:

javascript - 是否可以捕获 window.location.replace 事件?

javascript - 链接未使用 ajax/jquery 从数据库加载数据

javascript - Karma Jasmine Angular 错误 : [$injector:nomod]

angularjs - 将 ngRoute 与 Express 后端一起使用

angularjs - 在 View 中显示所有 $scope 变量 - AngularJS

javascript - IE9 中的 Angular JS 页面加载问题

angularjs - 使用 $mdDialog.confirm() 关闭父页面

javascript - 有状态组件调用功能组件的 Props 更改类型

javascript - 样式化 innerHTML 输出

javascript - 使用AR.js扫描二维码并根据扫描值显示对象