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:

pip install pymssql fails with 'sqlfront.h': No such file or directory

I've tried to install pymssql on Windows using command line: pip install pymssql The operation fails with an error: fatal error C108...