HIRA THAKUR
HIRA THAKUR

Reputation: 17757

pass data from controller to directive's link?

In my controller :

myApp.controller('homeCtrl', function($scope, $rootScope, $state,  'red';
    $rootScope.$on('new_story', function(event, data) {
        $scope.cardObj = {key:'value'};
    });
});

In my HTML :

<div clickmeee ></div>
<div id="feedContainer" card='{{cardObj}}'> </div>

In my directive :

myApp.directive('clickmeee', function($compile, $rootScope) {

            return {
                restrict: 'A',
                scope: {
                    card: '@'
                },
                link: function(scope, element, attrs) {
                    element.bind('click', function() {   
                            scope.$watch('card', function(newVal, oldVal) {
                                alert(scope.card);
                            });         
                            });
                        }
                    };
                });

How do I pass data from controller to this directive. I compile some html and prepend it to the div. All of that is sorted out but I need some data from object I am trying to pass.

Any help??

Upvotes: 0

Views: 1259

Answers (3)

JB Nizet
JB Nizet

Reputation: 691635

There are several problems in your code:

  • you define a scope attribute named 'card', but you use cardObj instead
  • you use a watch that is completely unnecessary. And worse: you create a new watch every time the element is clicked
  • you don't define any card attribute on your clickmeee element. Instead, you're placing it on another element, on which the directive is not applied
  • you're passing the attribute with '@'. That works, but the directive will receive a string, containing the JSONified object, rather than the object itself
  • you're not showming us where you emit an event that will initialize cardObj in the controller scope

Here is a plunkr showing a working version of your code.

Also, note that using bind('click') is a bad idea. You'd better have a template in your directive and use ng-click in the template, or simply not use a directive at all and just use ng-click directly on the div element.

Upvotes: 2

Benedikt K&#246;ppel
Benedikt K&#246;ppel

Reputation: 5109

You should watch the card object:

myApp.directive('clickmeee', function() {

    return {
        restrict: 'A',
        scope: {
            card: '@'
        },
        link: function(scope, element, attrs) {
            scope.$watch('card', function(value) {
                console.log(value);
            });         
        }
    };
});

And:

<div clickmeee id="feedContainer" card='{{cardObj}}'> </div>

Whenever the controller changes the cardObj, the directive's watch on card is triggered:

$scope.$apply(function() {
    $scope.cardObj = "test";
}

Upvotes: -1

Quy
Quy

Reputation: 38

Bad news. You are doing it wrong all the ways.

Firstly

card='{{cardObj}}' >

this one should be put in the

<div clickmeee ></div>

So you can take it as binded scope variable in your directive registration

Secondly

If you managed to use '@' syntax

card: '@'

it will turn your input to string, not a binded scope. Use '=' instead.

In the end

You dont need to use watch here:

scope.$watch('card', function(newVal, oldVal) {
    alert(newVal);
});  

since scope.card is binded via '=' connector. Just simple use alert(scope.card). (Need to warn you that alert an object is not a good idea)

I have tried your code here: plunker. Changed a litte bit by using cardObj as string for easier presentation. Does it match your work?

Upvotes: 2

Related Questions