最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Directive : $observe, class attribute change caught only once - Stack Overflow

programmeradmin2浏览0评论

I have a directive changing the style of a div and would like to be notified by $observe each time the class of the element changes. The problem is that it happens at directive creation but not after. Here is the code and a fiddle

<div ng-app="testObserve">
    <div ng-controller="Ctrl2"> 
        <span class="rouge" ng-click="toggleClass()" my-test>Coucou</span>
    </div>
</div>

angular.module('testObserve', [])
    .controller('Ctrl2', function ($scope) {})
    .directive('myTest', function () {

    function link(scope, element, attrs) {

        scope.toggleClass = function () {
            if (element.hasClass('rouge')) {
                element.removeClass('rouge');
            } else {
                element.addClass('rouge');
            }
            console.log( 'I bee ' + element[0].outerHTML );
        };

        attrs.$observe('class', function (val) {
            console.log('class has changed' + val);
            debugger;
        });
    }

    return {
        link: link
    };
});

Is this normal behavior?


Ok I found, it has to be ng-class instead of class both in the html and the js code (it is in the documentation).

The fixed js is here.

So I change a bit the question : if another js changes the class, but not ng-class, how may I observe that ?


To answer to @koolunix's question (and yes unix is kool :) ) about if js is in the angular scope, actually I want to use angular bootsrap dropdown and trigger something when the drop down opens or closes.

Strangely, although it is an angular module, it uses class instead of ng-class. So I did not find a way to catch that information from the outside as it only appears as the appearance of the 'open' class.

I think the submitted answer works, but I still need to try.

As a work around I duplicated the ui-bootstrap directive and added what I needed inside.

Thanks!

I have a directive changing the style of a div and would like to be notified by $observe each time the class of the element changes. The problem is that it happens at directive creation but not after. Here is the code and a fiddle

<div ng-app="testObserve">
    <div ng-controller="Ctrl2"> 
        <span class="rouge" ng-click="toggleClass()" my-test>Coucou</span>
    </div>
</div>

angular.module('testObserve', [])
    .controller('Ctrl2', function ($scope) {})
    .directive('myTest', function () {

    function link(scope, element, attrs) {

        scope.toggleClass = function () {
            if (element.hasClass('rouge')) {
                element.removeClass('rouge');
            } else {
                element.addClass('rouge');
            }
            console.log( 'I bee ' + element[0].outerHTML );
        };

        attrs.$observe('class', function (val) {
            console.log('class has changed' + val);
            debugger;
        });
    }

    return {
        link: link
    };
});

Is this normal behavior?


Ok I found, it has to be ng-class instead of class both in the html and the js code (it is in the documentation).

The fixed js is here.

So I change a bit the question : if another js changes the class, but not ng-class, how may I observe that ?


To answer to @koolunix's question (and yes unix is kool :) ) about if js is in the angular scope, actually I want to use angular bootsrap dropdown and trigger something when the drop down opens or closes.

Strangely, although it is an angular module, it uses class instead of ng-class. So I did not find a way to catch that information from the outside as it only appears as the appearance of the 'open' class.

I think the submitted answer works, but I still need to try.

As a work around I duplicated the ui-bootstrap directive and added what I needed inside.

Thanks!

Share Improve this question edited Feb 11, 2014 at 19:51 unludo asked Feb 10, 2014 at 14:14 unludounludo 5,0167 gold badges51 silver badges74 bronze badges 2
  • This depends on whether this other js is within or outside of the scope of Angular. Could you be more specific? – koolunix Commented Feb 10, 2014 at 19:04
  • @koolunix please see my modified question – unludo Commented Feb 11, 2014 at 19:54
Add a ment  | 

1 Answer 1

Reset to default 5

$observe is used to observe the value changes of attributes that contain interpolation.

For example:

<span class="{{something}}">Hello</span>

In your example you can use $watch instead to watch for changes on the class attribute like this:

scope.$watch(function() {
  return element.attr('class');
}, function(newValue, oldValue) {
  if (newValue !== oldValue) { // Values will be equal on initialization
    console.log('class has changed to: ' + newValue);
  }
});

Working example: http://plnkr.co/edit/SImhYTkN11eAECC8gDXm?p=preview

发布评论

评论列表(0)

  1. 暂无评论