Our rental application utilizes an API call to populate an array, triggering an ngRepeat and generating a list of divs displaying basic rental property information.
Upon clicking a specific property, another API call is made to populate an interior ngRepeat with a list of tenants. Some properties contain up to 100 listed tenants (past and present). The tenant divs are expandable, providing access to various functionalities such as downloading rental agreements and viewing history. All these features are encapsulated within a single directive consisting of multiple ng-includes.
For those still following, there's an outer ngRepeat and an inner ngRepeat containing a significant directive within it.
<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>
The tenant-menu
directive along with all the included ngIncludes and watchers are rendered when expanding the property list, even though they are not immediately visible. Clicking on a tenant merely adjusts the div height to reveal the internal menu.
The design structure of this UI has severe performance implications. With over 15,000 watchers for elements that are initially hidden, processing actions on one tenant unnecessarily triggers the digest loop for all tenants. While data retrieval takes less than a second, rendering a list of 60 applicants can take almost 20 seconds. When the directive is completely removed (resulting in no action upon clicking a tenant), the loading and rendering time reduces to just 2-3 seconds.
Is there a way to defer attaching the directive until a tenant is clicked? Rather than simply adjusting the height to show what's inside the div, I prefer to append the entire directive upon the click event and then expand the height accordingly. Additionally, when the tenant is collapsed, I aim to remove any watchers and perform proper cleanup.
Edit: Below is the code for the sliding directive mentioned earlier. It's worth noting the use of a click event bound internally, which may need further examination in terms of Angular best practices. Leveraging compile, postlink, and prelink functions alongside the proposed solution could potentially optimize the performance issues outlined above due to legacy code inheritance.
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
(complimenting_text) {content_summary}
example_list: [design1](link1), [design512345](https://www.link.com)
element[sliding_properties] != true:
limit_access(change_background_colors)
access_forbidden{error_message}
"forloop": let x=0 || y<=5 || increment "y"}};
output('{{x*e};}') |
delete ('function') from codes
!@#$12 %^&*++
if(condition) {!run_code};
while(({boolean})) {},
bind(data);}