Harry
Harry

Reputation: 55029

AngularJS directive not reacting to attribute change

I have a chat directive that I use to place a chatroom on the page.

mod.directive('chat', function () {
  return {
    templateUrl: '/chat',
    replace: true,
    scope: { 
      chatID:'@chat',
    },
    controller: function ($scope, $element, $timeout) {
      var id = $scope.chatID
      ...
    },
    link: function ...
  }
})

HTML looks like this:

<div class="chat" chat="{{currentChatID}}" ui-view="currentChat"></div>
<div class="content" ui-view="mainContent"></div>

This is in a file called "standard"

mod.config(function($stateProvider) {
  $stateProvider.state('standard', {
    views: {
      'main': {
        templateUrl: '/tmpl/standard',
        controller: function($scope, $timeout) {
          $scope.currentChatID = ''
          $scope.setCurrentChatID = function(newID) {
            $scope.currentChatID = newID
          }
        }
      }
    }
  })
})

I'm using angularjs-ui-router to create a parent view with the chat directive providing a chat inside that view. This works fine on first page load, the chat loads up. But when I change the page/chat room, I use another controller to run setCurrentChatID(). This changes the currentChatID for the chat element in the DOM, I also see the chat element's properties change to the new ID in angularjs-batarang but the chat directive's controllers do not run. How do I get this to work properly / activate the chat's controllers when the chatID changes?

Thanks.

Upvotes: 4

Views: 5786

Answers (1)

Dan
Dan

Reputation: 63139

It's hard to say without seeing the rest of your chat controller's code, but you may need a $watch inside your chat controller like:

$scope.$watch('chatID', function(newValue, oldValue) {
    // run some code here whenever chatID changes
});

EDIT: For more about the $digest loop and Angular's runtime operations, see this AngularJS Guide. (Check the Runtime section)

For more about controllers, see this AngularJS: Understanding Controllers guide. Here are the key points relevant to your question:

Controllers should be used only to:

  1. Set up the initial state of a scope object.
  2. Add behavior to the scope object. (to include creating a $watch, etc.)

The $digest loop processes only:

  1. the $evalAsync queue
  2. the $watch list

Upvotes: 4

Related Questions