Using AngularJS to manipulate the DOM after the view has completely loaded

Sorry for the lengthy explanation - I hope it doesn't deter too many readers. While my current setup is functional, I'm unsure if it's the most optimal way to go about things. Therefore, I'm seeking some guidance.

I have a webpage where I utilize the window size to determine the placement of a varying number of elements. These elements are spread out based on the window's dimensions, and I then use the Canvas element to draw lines connecting each element to a central point.

The challenge I face is determining when all elements have been generated and are prepared for resizing and repositioning.

The structure of my HTML looks like this:

<div class="panel">
    <div class="panel_content">
        <div class="input_mapping" ng-repeat="input in inputs" mapping-resize>
            {{input.name}}
        </div>
    </div>
</div>
<div class="panel">
    <div class="panel_content">
        <div class="central_mapping">
            {{mapping.name}}
        </div>
    </div>
</div>
<div class="panel">
    <div class="panel_content">
        <div class="output_mapping" ng-repeat="output in outputs" mapping-resize>
            {{output.name}}
        </div>
    </div>
</div>

To resize everything, I am using the directive mapping-resize, which triggers for each ng-repeat. Ideally, I want it to run only once, after all child elements have been created. However, if I place the directive on the parent div (panel_content), it does not recognize the child elements at that stage of execution and therefore fails to reposition them.

My current directive code looks like this:

app.directive('mappingResize', ['$timeout', function($timeout) {
    return function(scope, elem, attrs) {

        if(scope.$last) {
            $timeout(function() {
                positionElements();
            });
        }
    }
}]);

positionElements() contains all the logic for positioning the elements once they are generated. Although it works well, there might be a more "angular way" to approach it (currently, it relies heavily on jQuery).

In the directive, I employ the $last property to call positionElements() only when it's the last element in the ng-repeat loop, as I require knowledge of all elements to position them correctly. Additionally, I use $timeout to ensure the code runs after the page render.

My question is: could this be optimized further?

Currently, I call positionElements() twice - once for input mappings in ng-repeat and once for output mappings. Ideally, I would prefer to call it just once when all mapping elements are ready. Utilizing $timeout and $last doesn't feel elegant; it seems like there should be an event that signals when the view is completely rendered, yet my search efforts have proved futile.

Any suggestions or advice on the above scenario would be greatly appreciated.

Answer №1

Implement $timeout and place your directive at the bottom of your page:

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

app.controller('MainCtrl', function($scope) {
  $scope.model = { items: [1,2,3,4,5] };
});

app.directive('directive', function () {
  return {
    link : function (scope, elem, attrs) {
      console.log(attrs.index);
    }
  }
});

app.directive('lastDirective', function ($timeout) {
  return {
    link : function (scope, elem, attrs) {
      $timeout(function () {
        // arrange elements here
        console.log(attrs.index);
      });
    }
  }
});

HTML:

  <body ng-controller="MainCtrl">
    <div ng-repeat="item in model.items" directive index="1"></div>
    <div ng-repeat="item in model.items" directive index="2"></div>
    <div last-directive index="3"></div>
  </body>

Check the console to observe the order of directive execution

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

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

A div element with the class name "draggable" is

One of my functions sends notifications to a page by prepending a main div with the notification. Here is the function: function displayNotification(notificationTitle, notificationContent, notificationColor, notificationSize) { console.log('Attem ...

Working with JSON data retrieved from a PHP and MySQL backend in an AngularJS application

Having difficulty handling the JSON response from PHP. I am using AngularJs to display the received JSON data. As a newcomer to Angular, I attempted a basic exercise and would appreciate some assistance. Thank you in advance. index.html <!DOCTYPE HTML ...

JavaScript preloader function isn't functioning properly when paired with a button

I'm currently working on developing a preliminary landing page for my game using JavaScript. I have integrated a class that overlays my main content, and added an 'onclick' function named fadeOut() for my button in JavaScript. However, the f ...

Creating a mat-tree component in Angular Material 6.0.1: Step-by-step guide

I am encountering an issue with my material angular mat-tree based application. The code runs without errors, but the values are not displayed on the screen. I need help resolving this problem so that I can proceed with the development. Upon opening the a ...

Tips for refreshing a page in Vue.js

I am facing an issue with updating a table on my page after deleting a row. Each row in the table has a delete button and I have tried using window.location.reload() but it didn't work. </va-card> <br/> <va-card > ...

Is there a way to transfer table row data to another table by simply clicking on the corresponding checkbox in the same row?

I'm working with a table that includes 4 fields: service, amount, tax, and action. My challenge is to have the data from any row in the first table added to a second table when its checkbox is selected. The second table should have the same fields a ...

Is there a way to import TypeScript modules from node_modules using browserify?

After successfully running tsc, I am facing difficulty understanding how to import TypeScript modules from node modules. The crucial section of my gulp file is as follows: gulp.task('compile-ts', ['clean'], function(){ var sourceTsF ...

Tips for showing an empty string in an Angular expression when the value is equal to zero

<div>{{a.value | number:0}}</div> I currently have this code snippet. Is there a way to display only empty quotes if the value is 0 directly within the same line? Or do I need to filter it out in a controller? Thank you for your help! ...

One of the quirks of Angularjs is that the ng-enter animation will only be

The initial animation only occurs the first time. I am utilizing Angularjs version 1.2.22 Here is the CSS that I am using : .ng-enter { animation: bounceInUp 2s; } .ng-leave { animation: bounceOutUp 2s; } And this is the route configuration : ...

Automating tests with d3 technology

Currently, I am facing a challenge with testing d3-based Angular components. My initial plan was to utilize Selenium IDE or Kantu for this purpose, but it appears that these tools are unable to capture interactions with SVG elements. Can anyone suggest a ...

Conceal a Component within an Embedded Frame

Hey there! I've been attempting to hide a header within an iframe, but it seems like my code isn't doing the trick. Could someone take a look and help me diagnose why the header is still visible? Thanks in advance! <iframe id="booking_iframe" ...

Combine two elements in an array

I am faced with a challenge in binding values from an Array. My goal is to display two values in a row, then the next two values in the following row, and so on. Unfortunately, I have been unable to achieve this using *ngFor. Any assistance would be greatl ...

An error occurred when trying to set a cookie using Set-Cookie in a react application

Currently, I am immersed in a small project that involves user authentication via email and password before gaining access to their individual profiles. The backend operates on cookies which are established once the correct email and password combination i ...

Maximizing memory efficiency in Javascript through array manipulation strategy

In the project I am working on, I maintain a history of changes. This history is stored as an array containing objects, each with two arrays as properties. When adding a new history snapshot, it appears as follows: history.push({ //new history moment ...

steps for executing a Google script

In my program, the structure is as follows: // JavaScript function using Google Script 1. function F1() { ...... return (v1); } // HTML code for Google 1. <script> 2. function F2() { 3. alert ( 1 ); 4. function F2(); 5. alert ( 2 ); 6 ...

angularjs dropdown - customize selected item appearance

My dilemma involves a list of countries, each with a code and name. When the list is expanded, I aim to show "code + name" (e.g. "+44 United Kingdom"). However, once a country is selected, I only want to display the code ("+44"). Is it achievable using Ang ...

What is the process of converting TypeScript to JavaScript in Angular 2?

Currently diving into the world of Angular 2 with TypeScript, finding it incredibly intriguing yet also a bit perplexing. The challenge lies in grasping how the code we write in TypeScript translates to ECMAScript when executed. I've come across ment ...

Modal Pop-ups Failing to Open on Subsequent Attempts

My table consists of buttons on the right-hand side for a menu. The first button in the menu is supposed to open a modal box upon clicking. However, the first buttons in the subsequent rows do not function as expected and fail to open the modal. Refer to t ...

Controlling dynamic fields within a web page - Utilizing Postgres and MongoDB databases

My application utilizes MongoDB and PostgreSQL as databases, with AngularJS for the UI. A key requirement is the ability to dynamically add fields (columns) on pages, allowing users to define their attributes when adding these fields to the system. In add ...

Angularjs - Techniques for verifying undefined values in select options

How can I ensure that the select value from the select tag is not undefined to prevent users from forgetting to make a selection? Despite attempting the following JavaScript code, I am still encountering an undefined error in the console log without any a ...