iLemming
iLemming

Reputation: 36166

$watch on clientWidth isn't working

Inside of my directive I have this and it works only in the beginning, and whenever I resize later it never fires.

    scope.$watch ->
        cw: element[0].clientWidth
    ,(newValue, oldValue)->
        if newValue.cw isnt oldValue.cw
            console.log "changed"
    ,true

Upvotes: 1

Views: 853

Answers (3)

Owen Calzadilla
Owen Calzadilla

Reputation: 86

Just like Jason Goemaat said, its because Watches are only checked on a $digest cycle Depending on how the way your element is resized maybe this example may help you. Here is a menu that expands it self when pressed on the arrow.

<div class="menu" ng-class="{'expanded' : main.expanded}">
    <div class="menu-handler" ng-click="main.expanded = !main.expanded">
    </div>
</div>

The menu is expanded by a ng-click that makes a change on the scope, in this case its a boolean var that acts as a flag. As the opening of the menu is made throught the change in the scope it calls the $digest cycle iterating through all $watch.

scope.$watch(function() {
      return element[0].clientWidth;
}, function(oldValue, newValue) {
      console.log(oldValue, newValue);
});

You can view the full example in this JSfiddle https://jsfiddle.net/owenbcal/zf17s0mL/ Hope i was helpfull.

Upvotes: 1

Ed_
Ed_

Reputation: 19098

Your function looks right to me, but it's important to note that it won't fire on resize unless you manually trigger a digest on the resize event.

Without this, angular doesn't realise there's been an event that should trigger a digest, and so none happen.

Try adding this (remember to inject $window):

angular.element($window).bind('resize', ()->
  scope.$apply();
)

Upvotes: 1

Santiago Rebella
Santiago Rebella

Reputation: 2449

the way I know about watching this kind of values is making a function that is fired once the value changes so then I watch that function :

in the service:

this.getDataOut = function () {
    return self.dataOut;
};

in the controller:

$scope.$watch(dataService.getDataOut, function() {
    $scope.dataOut = dataService.dataOut; 
});

Upvotes: 0

Related Questions