robe007
robe007

Reputation: 3927

How to '$parse' a scope object in a directive passing the entire object

If I have this controller:

myApp.controller('ctrl', function ($scope) {    
 $scope.obj = {
  name: "John",
  lastname: "Preston"
 }
});

with this html

<body ng-controller="ctrl">
    <div my-attr="obj" my-directive>Click here</div>
    <pre>{{obj | json}}</pre>
</body>

I want to change the value of lastname in a directive with $parse. I know that if I pass the object property like this:

<div my-attr="obj.lastname" my-directive>Click here</div>

This directive do the work:

myApp.directive('myDirective', function( $parse, $log ) {
    return function( scope, el, attrs ) {

        var model = $parse( attrs.myAttr );

        $log.log( model(scope) );

        el.bind('click', function() {
            model.assign(scope, "Watts");
            scope.$apply();
            $log.log( model(scope) ); // Now here obj.lastname is Watts
        })
    }
});

But how could be the code inside the directive without passing the property? I mean, like this: my-attr="obj"

Upvotes: 0

Views: 441

Answers (2)

IHTS
IHTS

Reputation: 31

Yes, you can pass in the entire object. but then in the directive you have to populate all the properties of the object. For example:

html:

<div my-attr="obj" my-directive>Click here</div>

in your directive:

el.bind('click', function() {
        model.assign(scope, {lastname:'Watt', gender: 'Male'});
        scope.$apply();
        $log.log( model(scope) ); // Now here obj.lastname is Watt
    })

I probably won't do that, but that's how I would do it

Upvotes: 1

robe007
robe007

Reputation: 3927

Ok, I found 2 ways to get this:

1) $parse (my favorite)

I just got it using: $parse( 'obj.lastname' ); on this way:

The html:

<div my-directive>Click here</div>

The directive:

myApp.directive('myDirective', function( $parse, $log ) {
    return function( scope, el, attrs ) {

        var model = $parse( 'obj.lastname' );

        $log.log( model(scope) );

        el.bind('click', function() {
            model.assign(scope, "Watts");
            scope.$apply();
            $log.log( model(scope) ); // Now here obj.lastname is Watts
        })
    }
});

2) $eval (interesting)

The html:

<div my-attr="obj" my-directive>Click here</div>

The directive:

myApp.directive('myDirective', function( $parse, $log ) {
    return function( scope, el, attrs ) {

        var model = scope.$eval(attrs.myAttr);

        $log.log( model );

        el.bind('click', function() {
            model.lastname = 'Watts';
            scope.$apply();
            $log.log( model ); // Now here obj.lastname is Watts
        })
    }
});

Any other ideas?

Upvotes: 1

Related Questions