user3603310
user3603310

Reputation:

AngularJS: Pass object from directive to controller

In my directive, I'm instantiating an object.

I'd like to pass this object to the scope of the controller I associate with the directive. How do I do that?

Please keep in mind this is an isolated code for you to understand the issue. In the actual issue it won't help to instantiate that object inside of the controller.

I know that the scope object in the directive is for passing values that are specified in the HTML, I wrote it that way to help you understand what I'm trying to do.

angular.module('test', [])

.controller('test', ['$scope', function($scope) {
    alert($scope.obj); //Needs to contain {value: 'bla'}

}])

.directive('pTest', ['$compile', function($compile) {
    var object = {value: 'bla'};

    return {
        scope: {
            obj: object //how can I do that?
        },
        controller: 'test'
    };
}]);

Upvotes: 3

Views: 4650

Answers (2)

A.B
A.B

Reputation: 20445

You can have two solution

Solution 1: use '=' in isolated scope, it binds a local/directive scope property to a parent scope property.

 .directive('ptest', ['$compile', function($compile) {
        var object = {value: 'changed value'};

        return {

          scope: {
                iobj:"="
            },
          template : "<div>{{iobj.value}}<div>",

             link: function(scope,elem,attr){
             scope.iobj=object ;
          }
        };
    }]);

in html

 <div ng-controller="testCtrl">
  <div ptest iobj="object"></div>
</div>

Solution 2: use $controller service and make testCtrl as parent and copy its all scope to controllers scope

.directive('ptest', ['$compile', function($compile,$controller) {
                var object = {value: 'changed value'};

                return {


                     controller:function($scope,$controller){

                    $controller('testCtrl', {$scope: $scope});
                       console.log($scope.object.value);
                       $scope.object = object;
                     }
                };
            }]);

working example for '=' solution 1 :

angular.module('test',[])
.controller('testCtrl',function($scope){


  $scope.object = {value:'intial value'};



})



.directive('ptest', ['$compile', function($compile) {
        var object = {value: 'changed value'};

        return {
          //replace:true,
          scope: {
                iobj:"="
            },
          template : "<div>{{iobj.value}}<div>",
            
             link: function(scope,elem,attr){
             scope.iobj=object ;
          }
        };
    }]);
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="test"  ng-controller="testCtrl">
  {{object.value}}
   <div ptest iobj="object"></div>
</div>

Working example for solution 2 with $controller

  angular.module('test',[])
    .controller('testCtrl',function($scope){


      $scope.object = {value:'intial value'};



    })



    .directive('ptest', ['$compile', function($compile,$controller) {
            var object = {value: 'changed value'};

            return {
              
                
                 controller:function($scope,$controller){
                 
                $controller('testCtrl', {$scope: $scope});
                   console.log($scope.object.value);
                   $scope.object = object;
                 }
            };
        }]);
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    <div ng-app="test"  ng-controller="testCtrl">
      {{object.value}}
       <div ptest ></div>
    </div>

Upvotes: 3

Geoff Genz
Geoff Genz

Reputation: 2119

You can do this in the link function of the direction. Since you want to set the value on the scope, you can use the scope parameter of the link function. You can also set the object on the controller, since The fourth argument (optional) argument to the link function is the controller for the directive.

.directive('pTest', ['$compile', function($compile) {
    var object = {value: 'bla'};

    return {
        controller: 'test',
        link: function(scope, elements, attrs, controller) {
           scope.obj = object;
           // or
           controller.obj = object;
        }

    };
}]);

Now that assume you don't want to isolate your scope by using a "scope" member in the return of your directive. From your example I don't think you actually want an isolated scope. (Regardless, the link function would work there too.)

Upvotes: 3

Related Questions