2015-01-09

AngularJS Directive: Accessing an DOM element with a dynamic ID in an asynchronous directive

Hi,

This problem was really bothering me for few months. In earlier cases I tried to avoid it, but today I could not hide from it any longer. And the thing is that there was no post on any other place that could solve this matter... So here it goes.

You're writing a directive in AngularJS, and you want to access one of the DOM elements declared within its template.
Usually you do it through the linking function (post section in the compile) or in the directive controller, by injecting and using '$element', as explained here.

But, in my case, I had to access an element using its ID and this ID was dynamic.

So, my template contains:

   
<div>
    <div ng-attr-id="{{ 'something_' + dynamicValue }}"></div>

</div>
     
And my directive contains:

{
    templateURL: 'pathToTempalte',
    scope: {
        dynamicValue: '@'
    },
    link: function(scope, element, attributes) {
        attributes.$observe('dynamicValue', function(value) {
            element.find('#something_' + value);
        });
    }
}

The element.find doesn't work, because nothing is actually compiled and rendered yet here.

The solution, at the moment, is to use ''$timeout".

$timeout, even with '1' as a parameter, will only be executed after everything has been rendered, and outside of the asynchronous scope. Therefore using element.find inside its function, will deliver the expected result:

{
    templateURL: 'pathToTempalte',
    scope: {
        dynamicValue: '@'
    },
    link: function(scope, element, attributes) {
        attributes.$observe('dynamicValue', function(value) {
            $timeout(function() {
                element.find('#something_' + value);
            }, 1);
        });
    }

}

Happy coding

No comments:

Natural Language Processing :: A beginner’s (brief) guide for working on NLP problems

This article  was written for the Data Science Society's Datathon held on February 2018, as an answer to questions from the participant...