1

I have the following problem in angularjs. I want to use an UI libary that injects some html code itself (Metro UI CSS) and I have troubles to getting the execution order right.

A simple example: http://metroui.org.ua/hint.html

If I declare in html:

<span data-hint="My hint"></span>

The UIjs will create the html elements needed for the hint display. Nofurther script code has to be added. Well actually when you load the js the following code gets executed: $('[data-hint]').hint();

Since the angular created html doesn't exist when I load the javascript, it doesn't work at first at all.

I believe I need an angular directive to solve the problem (and in parts it does) - I created the fowlling directive:

app.directive('hints', function() {
return {
    link: function() {$('[data-hint]').hint()}
};
});

The following does work, even if this is in html created by angular:

<span hints data-hint="the text for my hint">test</span>

The following doesn't work (at least it doesn't behave the way I'd like to):

<span hints data-hint="{{something}}">Test</span>

The hint text will display literally {{something}} and not whatever is behind the angular expression. I tried already to create template like, but the result is still the same:

app.directive('hints', function() {
return {
    template: '<span data-hint="{{something}}">Test</span>',
    link: function() {$('[data-hint]').hint()}
};
});

Any hints on how to solve that problem would be greatly appreciated.

1 Answer 1

1

The main problem seems to be that if you attach the hint() in the link function, jquery takes the old value before angular has evaluated it. One option would be to wrap $timeout(function(){..}) around element.hint(), but I use that hack too much already, and it doesn't solve another problem: the hint needs to update when the $scope changes (if it depends on the $scope). To solve that problem we can add a $watch function and update the hint value when needed.

So, in conclusion:

/* This directive triggers automatically on data-hint as well */
app.directive('hint', function($timeout) {
    return {
        link: function(scope, element, arguments) {

            /* set the value of the hint, then attach the metro-hint widget */
            element.data('hint' , arguments.hint).hint();

            /* watch for changes in the value so the hint gets updated */
            scope.$watch(function(){
                return arguments.hint; 
            }, function() {
                element.data('hint' , arguments.hint);
            });
        }
    };
});

(Tested with jquery 1.10.2, jquery-ui 1.10.3 and angular 1.2.6)

Sign up to request clarification or add additional context in comments.

1 Comment

Thank you very much - helped me alot to understand angularjs better.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.