Directive : $observe, class attribute change caught only once

瘦欲@ 提交于 2019-12-23 18:32:32

问题


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 become ' + 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!


回答1:


$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



来源:https://stackoverflow.com/questions/21679534/directive-observe-class-attribute-change-caught-only-once

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!