Wednesday 22 January 2014

Angular directives - isolate scope

If you don't want a directive to use its parent's scope, create isolate scope:

app.directive("widget", function() {
    return {
        scope : {},    // creates isolate scope
        ...
}

When using isolate scope, obtain access to the parent scope by binding some members:

app.directive("widget", function() {
    return {
        scope : {
            foo: '@' // binds to parent's $scope.foo
        },
        ...
}

3 bindings to parent scope exist:

    '@': 1-way, by value, as a string (updates in the directive are not propagated to the parent scope)
    '=': 2-way, by reference (updates in the directive will update the parent scope)
    '&': expression (the expression is executed in the context of the parent scope)

1-way binding:

app.directive("widget", function() {
    return {
        restrict: 'E', // can only be used as an element
        scope: {
            foo: '@'   // imports $scope.foo by value
        },
        link: function(scope, element, attrs) {
            // do something with attrs.foo
        }


<widget foo="blah"></widget>

In the directive's link function, attrs.foo === "blah".

Model expressions can be parsed too:

<widget foo="{{ model }}"></widget>

In the directive's link function, attrs.foo is a string containing the value in $scope.model.

2-way binding:

app.directive("widget", function() {
    return {
        restrict: 'E', // can only be used as an element
        scope: {
            foo: '='   // imports $scope.foo by reference
        },
        link: function(scope, element, attrs) {
            // do something with attrs.foo
        }


<widget foo="bar"></widget>

In the directive's link function, attrs.foo === $scope.bar. Updating attrs.foo will result in $scope.bar being updated too.

expression binding:

app.directive("widget", function() {
    return {
        restrict: 'E', // can only be used as an element
        scope: {
            foo: '&'   // foo() executed as expression on $scope
        },
        link: function(scope, element, attrs) {
            // attrs.foo() will execute the expression
        }


<widget foo="bar()"></widget>

In the directive's link function, attrs.foo() will execute $scope.bar()

pass parameters to expression:

Special syntax is required to pass parameters to the expression.

In the directive, foo({p1: val}) will pass val to expression foo, which is function bar(p1) on $scope

No comments:

Post a Comment