Wolf359
Wolf359

Reputation: 2725

AngularJS 1.6: Directive inside Directive Template works only first time

I hava a directive "avatar", which takes a 'user' object and displays an image of the user.

This works fine.

Now I have another directive 'user', which displays the name of given 'user' object and includes withing its template the directive.

This works.. THE FIRST TIME.

when I update the 'user' object, only the name changes, the image (avatar) does NOT change.

My Problem : How can I make it work ?

Avatar directive :

(link function : if user object does have a 'ext' property, it calculates an image path ('src'), otherwise it displays a standard template.jpeg)

directive('avatarSmall', function() {

  return {
    restrict: "E",
    replace: true,
    templateUrl: "scripts/directives/avatar/small.html",
    link: function(scope, element, attrs) {
      var r = "images/avatars/";
      var ext = scope.user.ext;
      r += ext != undefined && ext.length >= 3 ? scope.user.ID + "." + ext : "template.jpeg";
      scope.src = r;
    },
    scope: {
      user: '='
    }
  }
})

avatar template :

<div class="circle-wrapper-small">
  <img class="circle-img-small"
       ng-src="{{src}}">
</div>

user directive :

directive('user', function($compile) {
  return {
    restrict: "E",
    replace: true,
    templateUrl: "scripts/directives/user/template.html",
    scope: {
      user: '='
    }
  }
})

user template :

<div>
  <div class="media-left">
    <avatar-small user="user" />
  </div>
  <div class="media-body">
    <h4 class="media-heading">{{user.name}} {{user.surname}}</h4>
    </h5>
  </div>
</div>

Upvotes: 2

Views: 479

Answers (1)

P.S.
P.S.

Reputation: 16384

Because your avatar directive's code executes only ones, on directive init. If you want to update changes, you should $broadcast event to your directive and execute that code on $broadcast event.

For more info about $emit, $broadcast and $on event you can look through this post: Usage of $broadcast(), $emit() And $on() in AngularJS

Something like this:

Parent controller

$scope.user = {
  // object properties
}

// watch "$scope.user" for changes
$scope.$watch('user', function(newVal, oldVal){
    if(newVal !== oldVal) {
      // send new "$scope.user" to your directive
      $scope.$broadcast('userObjChanged', $scope.user);
    }
}, true);

And inside your directive

// catch event from parent's controller with new user object
$scope.$on('userObjChanged', function(event, data) {
  console.log(data); // here is the new user object from parent's scope
})

Upvotes: 2

Related Questions