Paul Cavacas
Paul Cavacas

Reputation: 4454

AngularJS isolated scope variable in directive not being set

I have a directive that looks like this:

return {
                restrict: 'A',
                replace: true,
                scope: {
                    personId: '@',
                    relationshipId: '@',
                    relationshipColumnsShown: '@',
                    personColumnsShown: '@'
                },
                templateUrl: 'app/views/communication/displayList.html',
                controller: controller,
                require: ['$scope', 'communicationLogDataService']
            };

You can see that there is a property called personId, which I am setting in the parent directive that is using the above directive like this

<div data-display-communication-log="" data-personId="currentPerson.Id" data-relationship-Columns-Shown="true" data-person-Columns-Shown="false">
</div>

You can see the personId is being set to the currentPerson.Id property from the parent directive. Now in the child directive I have a watch setup on the personId value. This watch is only getting hit once when the child directive is first loaded and the value is undefined. When it is first loaded the currentPerson on the parent doesn't exist yet because it is loaded Async. in the parent (not sure if this is what is causing the problem).

So my question is how can I pass the Id of the currentPerson from the parent into the personId of the child?

Upvotes: 0

Views: 3623

Answers (1)

Craig Squire
Craig Squire

Reputation: 2141

When you use the @ binding for the isolate scope, it only gives you the string value of the attribute, it does not evaluate it as an expression. I made a couple changes to your Fiddle to make it work. Needed an ng-app added, change the attribute name on your directive (camel case doesn't work in the template for attribute names) and put double curlies around your expression so it will get evaluated. I also added an input element so you can see the data get updated, you don't need a watch in this situation. Here is the result:

http://jsfiddle.net/pkqUn/3/

<div ng-app="myApp" ng-controller="myCtrl">  
    <input ng-model="currentLog.RelationshipId"></input>
      <div>
          *<div data-personselect="" data-relationship-id="{{ currentLog.RelationshipId }}"></div>*
      </div>
</div>

var myApp = angular.module('myApp',[]);

myApp.directive('personselect', function() {
    return {
        template: '<span> test {{ relationshipId }}<span>',
            restrict: 'A',
            replace: true,
            scope: {
                relationshipId: '@'
            }
        };
});

function myCtrl($scope){
    $scope.currentLog = {};
    $scope.currentLog.RelationshipId = 123;
}

Though this would prevent your directive from modifying the parent scope, I think it would be clearer to use the '=' isolate scope binding instead of '@', then you don't need the curlies around the attribute value.

Upvotes: 1

Related Questions