2

I'm trying to create an angular directive where I can set the options either via a single options object, or via some attributes. Here is an example of the kind of code:

app.directive('testElement', [function () {
    return {
        restrict: "E",
        scope: {
            options: "="
        },
        template: "<p><span>Name: </span>{{ options.name }}</p>",
        link: function (scope, element, attrs) {
            scope.options = scope.options || {};
            if (attrs.name)
                scope.options.name = attrs.name;
        }
    };
}]);

This works fine, in that the name value is displayed if I pass in a name via the options attribute. But if I pass a name via the name attribute, even though the link function does modify options, the value is not rendered.

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

I feel like I'm missing something fundamental in how the 2 way data binding of options works.

2 Answers 2

6

If you don't pass the two way data binding, angular gets angry:

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

Use optional binding (=?):

app.directive('testElement', [function () {
    return {
        restrict: "E",
        scope: {
            options: "=?"
        },
        template: "<p><span>Name: </span>{{ options.name }}{{ test }}</p>",
        link: function (scope, element, attrs) {
            scope.options = scope.options || {};
            if (attrs.name)
                scope.options.name = attrs.name;
        }
    };
}]);

Or if you are using an older version of angular, use $eval on attrs. options:

app.directive('testElement', [function () {
    return {
        restrict: "E",
        //Still can create isolate scope to not clobber parent scope variables.
        scope: {},
        template: "<p><span>Name: </span>{{ options.name }}{{ test }}</p>",
        link: function (scope, element, attrs) {
            scope.options = scope.$eval(attrs.options) || {};
            if (attrs.name)
                scope.options.name = attrs.name;
        }
    };
}]);
Sign up to request clarification or add additional context in comments.

2 Comments

You can use =?, see my answer
When using the optional double binding, the value is never passed(v1.3.10). scope: { selectedValue: '=?selectedValue' }. Works when removing the ?. Any idea how this can happen?
1

The directive requires a options parameter. In second case you have not supplied it and hence there is an error

If the isolated scope variable is optional use ? like

 scope: {
            options: "=?"
        }

See my plunkr http://plnkr.co/edit/eGh6r1X7HzY1sZIDYZ69?p=preview

and documentation on isolated scope here http://docs.angularjs.org/api/ng/service/$compile

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.