JayPrime2012
JayPrime2012

Reputation: 2692

AngularJS directive controller resolve interpolated attributes?

I just think the way I'm doing this sucks, and I'd like to know if there is a better way? Here's the directive:

<myDirective myAttribute="{{val}}"></myDirective>

Here's the directive's controller:

.controller('myDirective', ['$scope', '$attrs', function ($scope, $attrs) {
    $attrs.$observe('my-attribute', function (x) {
        $scope.myAttribute = x; // yay we finally have the interpolated value...
    });

This sucks for a number of reasons I don't want to get into. Is there a way to ensure that interpolated values are resolved before controller is called?

Ideally the $scope.myAttribute would have the interpolated value when the controller initializer is called.

EDIT: My primary goal is to get rid of the dependency on $attrs that this controller has.

Upvotes: 1

Views: 2730

Answers (2)

JayPrime2012
JayPrime2012

Reputation: 2692

Perhaps the best way is:

    link: function (scope, element, attrs) {
        attrs.$observe('myAttribute', function(x) {
            scope.setMyAttribute(x);
        });
    }

And then:

.controller('myDirective', ['$scope', function ($scope) {
$scope.setMyAttribute = function (x) {
    $scope.myAttribute = x; // yay we finally have the interpolated value...
});

EDIT: It took some doing... and here is a plunker demonstrating this bug:

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

Note the importance of using "templateUrl" in the child directive. Using just "template" and the bug disappears.

Upvotes: 1

jpsimons
jpsimons

Reputation: 28100

Angular 1.2 RC2 or maybe RC3 broke a few things with attribute interpolation. See this bug I filed:

https://github.com/angular/angular.js/issues/4525

Which just got fixed today. You should never see double curly braces in your value, that's a bug.

However, as soon as an attribute is found to use interpolation, it's evaluation becomes asynchronous. Even with this bug fixed, you should see it's synchronous value as undefined (i.e. if you just read the value right out of $attrs). That's why you have to $observe, so the value gets handed to you as soon as it's available.

As to why it can't be available right away, it's dynamic. The evaluation of {{val}} might be different all the time. That's just the nature of Angular, everything live updates all the time.

Upvotes: 1

Related Questions