Steve
Steve

Reputation: 8829

AngularJS nested components and scope

Here's a component for displaying a customer's address (please excuse the Jade):

address(style='{{addressStyle}}')
    strong {{clinic.businessName}}
    br
    span {{clinic.address.address1}}
    br
    span(ng-switch='{{clinic.address.address2 != null}}')
        span(ng-switch-when='true')
            | {{clinic.address.address2}}
            br
    span {{clinic.address.suburb}} {{clinic.address.state}} {{clinic.address.postcode}}
    br
    abbr(title='Phone') P:
    |  {{functions.formatPhoneNo(clinic.phone)}}
app.directive('clinicAddress', function($interpolate) {
    return {
        restrict: 'E',
        templateUrl: 'directives/clinicAddress',
        scope: { clinic: '=', functions: '=' },
        link: function(scope, element, attrs) {
            scope.addressStyle = attrs.style ? scope.addressStyle = $interpolate(attrs.style)() : '';
        }
    };
});

And another one, based on it, for displaying a customer's address wrapped in a hyperlink and with a map marker:

a(href='#!/clinic/{{clinic.urlFragment}}')
    div(style='width:50px;height:50px;background:url(/img/map/{{index+1}}.png) 190px 30px no-repeat;')
    clinic-address(clinic='clinic', functions='functions', style='background:url(/img/map/{{index+1}}.png) 190px 30px no-repeat;')
app.directive('indexedClinicAddress', function() {
    return {
        restrict: 'E',
        scope: { clinic: '=', index: '=', functions: '=' },
        templateUrl: 'directives/indexedClinicAddress'
    };
});

The problem is, when $interpolate runs in clinicAddress's directive, index is undefined because it's in indexedClinicAddress's scope. How can I make $interpolate use the parent scope, which I assume is the same scope as indexedClinicAddress?

Upvotes: 1

Views: 1602

Answers (2)

joakimbl
joakimbl

Reputation: 18081

Instead of using $scope.$parent and $interpolate you should should use the scope @ attribute - from the Angular directives guide:

@ or @attr - bind a local scope property to the value of DOM attribute. The result is always a string since DOM attributes are strings. If no attr name is specified then the attribute name is assumed to be the same as the local name. Given and widget definition of scope: { localName:'@myAttr' }, then widget scope property localName will reflect the interpolated value of hello {{name}}. As the name attribute changes so will the localName property on the widget scope. The name is read from the parent scope (not component scope).

app.directive('clinicAddress', function($interpolate) {
  return {
    restrict: 'E',
    templateUrl: 'directives/clinicAddress',
    scope: { clinic: '=', functions: '=', addressStyle:'@style' },
    link: function(scope, element, attrs) {
    }
  };
});

Upvotes: 3

Taylor Hakes
Taylor Hakes

Reputation: 616

Use

$scope.$parent

to get a reference to the parent scope

Upvotes: 0

Related Questions