hguser
hguser

Reputation: 36028

Pass object to directives without watching them

Generally we use the = to make two-way data binding when creating directives, for example:

app.module('main')
    .directive('dirTest'[function(){
        return {
            scope:{
                data:'='
            }
        }
    }])

Then we can use

<dir-test data="xx.data"></dir-test>

To pass the xx.data object to the directive, but it seems that this will make angular watch this expression.

This may be a waste of time once I do not care the change of the data or the data can hardly change.

Which means I need a one-way one-time data passwed to the directive, is this possible?


I ask this question because when I open the Batarang console, I found the regularinterceptedexpression cost too long and watch a lot of watchers. I think the page may run fast if I can remove some unused watchers.

I know there is a one-way from dom to directives by using @, however it seems that it just support string.

Upvotes: 3

Views: 1233

Answers (3)

maddygoround
maddygoround

Reputation: 2280

In angularjs if you create a directive with scope '@' then it will be Text bindings,which means you will be able to get the value of expression but making changes to it won't reflect back to the html page.so i believe if you create the directive in with scope @ then it will do a job for you.

app.module('main')
    .directive('dirTest'[function(){
        return {
            scope:{
                data:'@'
            }
        }
    }]

)

<dir-test data={{xx.data}}></dir-test>

Upvotes: 3

dfsq
dfsq

Reputation: 193261

It is possible, however you will need to eval data attribute and clone object yourself. The scope of this evaluation is going to be scope.$parent because this is the scope where the data comes from. If your directive doesn't need isolated scope (so you don't use scope config in the directive) then the attribute should be evaluated in the scope:

.directive('dirTest', [function() {
    return {
        scope: {
            something: '=' // something that might need two-way binding
        },
        link: function(scope, element, attrs) {
            scope.data = angular.copy(scope.$parent.$eval(attrs.data));
        }
    }
}]);

Demo: http://plnkr.co/edit/nDzqWaVH9QkluFJknOfy?p=preview

Upvotes: 1

alisabzevari
alisabzevari

Reputation: 8136

You can use Angular's one-time binding:

<dir-test data="::xx.data"></dir-test>

Note that it is available in Angular 1.3+. have a look at this article for more details: http://blog.thoughtram.io/angularjs/2014/10/14/exploring-angular-1.3-one-time-bindings.html

Upvotes: 0

Related Questions