Search code examples
javascriptangularjsangularjs-directiveangularjs-scopeangularjs-routing

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.


Solution

  • 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