3

I'm quite new to AngularJS and have already found a lot of helpfull answers on this forum, however the following item is driving me nuts.

First of all, let me tell you what I want to do: I do have an element, of which I would like to change the color property at runtime, but only when that particular element has the class 'active'.

Therefore, I have created a directive which looks like the following:

OfficeUIRibbon.directive('officeActiveStyle', function () {
    return {
        restrict: 'A',
        link: function (scope, element, attr) {
          scope.$watch(function() {
            return element.attr('class');
          }, function(newValue, oldValue) {
            if (newValue !== oldValue) { // Values will be equal on     initialization
              alert('Changed');
            }
          });
        }
    };
});

As far as my knowledge goes, this does watch the attribute class and the if check in their does make sure that the watch isn't triggered when the application is first launched.

Now, the class property of the element is being set by using the ng-click directive.

When I now execute the HTML, nothing happens. When I click the 'set active' link, the class is changed, but the directive doesn't show me an alert. (Why is that?). If I then change the class again, then the directive does show me an alert.

So, why, on the first click, the alert of the directive isn't triggered?

I've created a plunker for better understanding.

Hopefully, someone can tell me what's wrong with this because it's really blocking my work.

8
  • How is it that the class attribute value changes, without AngularJS doing it? Because - the answer to this question is really 'you don't want to'. Commented Jan 25, 2015 at 15:29
  • alert in plunker fires for me in 2 different browsers. Not sure why you want to watch the class when the class is being changed by data that you already have access to. What is the higher level objective other than just an alert? Commented Jan 25, 2015 at 15:30
  • In the plunker there are 2 links. Clicking on them execute a function in the controller which does change a value. The element itself has a ng-class attribute on that value. And indeed the alert does fire, but not when you click on any of the links for the first time. As from the second click the alert does show. Commented Jan 25, 2015 at 15:32
  • 1
    watching class makes no sense in the first place Commented Jan 25, 2015 at 15:34
  • 1
    This question is a complete X-Y problem. You made change color so vague and now what seems like best approach isn't. Where do the color values come from and why aren't you focusing on them? This is a classic case of an X-Y problem Commented Jan 25, 2015 at 16:06

1 Answer 1

3

You can, but you don't need to use directives to make this work nice. You could use ng-styleor just $scopelike the following example will show you. This Demo shows you, how easy make a "toggle" work in AngularJS by using directives.

var OfficeUIRibbon = angular.module('OfficeUIRibbon', []);

OfficeUIRibbon.directive('officeActiveStyle', function () {
    return {
        restrict: 'A',
        link: function (scope, element, attr) {
          scope.$watch(function() {
               officeUiRibbonActiveHexColor = '#f700ff';
          });
        }
    };
});

/**
 * CSS Hex color holder
 * @type {string}
 * @global
 */
 var officeUiRibbonActiveHexColor = '#ff0000';

/**
 * Active holder
 * @type {boolean}
 * @global
 */
 var officeUiRibbonActiveToggle = false;

// Defines the AngularJS 'OfficeUIRibbon' controller.
OfficeUIRibbon.controller('OfficeUIRibbon', ['$scope', '$http', '$animate', function($scope, $http, $animate) {


    $scope.toggle = function () {
      officeUiRibbonActiveToggle = officeUiRibbonActiveToggle ? false : true; //switch active state
    }

    $scope.getStyles = function () {
      if (officeUiRibbonActiveToggle) {
         return officeUiRibbonActiveHexColor; 
      }
    }
}]);

HTML-Template:

<!DOCTYPE html>
<html ng-app="OfficeUIRibbon">

  <head>
    <script src="https://code.angularjs.org/1.3.10/angular.js"></script>
    <script src="script.js"></script>
  </head>

  <body ng-controller="OfficeUIRibbon">
    <div
         office-active-style=""
         style="height: 200px; border: 1px solid black; background-color: {{ getStyles(); }}">Dit is een demo</div>

         <a href="#" ng-click="toggle()">Toggle</a>
  </body>

</html>

Solution 2

Optional: This is an other Demo. This demo shows you, how easy make a "toggle" work in angularjs without using directives.

var OfficeUIRibbon = angular.module('OfficeUIRibbon', [])

OfficeUIRibbon.controller('OfficeUIRibbon', ['$scope', '$http', '$animate', function($scope, $http, $animate) {

    /**
     * Active state holder
     * @type {boolean} 
     */ 
    var active = false;

    /**
     * Holds css color hex code
     * @type {string}
     */
    var color = '#ff0000';

    /**
    * Check active scope
    */
    $scope.toggleShow = function () {
      active = !active; //switch true false in the coolest way ;)
    }

    /** 
    * Check active scope
    */
    $scope.giveColor = function () {
      if (active) { 
         return color;
      } 
    }
}]); 

Your HTML-Template:

<!DOCTYPE html>
<html ng-app="OfficeUIRibbon">

  <head>
    <script src="https://code.angularjs.org/1.3.10/angular.js"></script>
    <script src="script.js"></script>
  </head>

  <body ng-controller="OfficeUIRibbon">
    <div office-active-style=""
         style="height: 200px; border: 1px solid black; background-color: {{ giveColor() }}">Dit is een demo</div>

         <a href="#" ng-click="toggleShow()">Toggle</a>
  </body>

</html>
Sign up to request clarification or add additional context in comments.

1 Comment

I've lost the link to the chat. Any idea on how I reconnect?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.