最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Angular JS directive, change a 2 way data binding in the link function - Stack Overflow

programmeradmin0浏览0评论

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.

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

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.

Share Improve this question asked Mar 26, 2014 at 15:15 James GauntJames Gaunt 14.8k2 gold badges41 silver badges57 bronze badges
Add a ment  | 

2 Answers 2

Reset to default 6

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

https://github./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;
        }
    };
}]);

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/api/ng/service/$pile

发布评论

评论列表(0)

  1. 暂无评论