0

I found some answers to this already - tried them however none of them work for me.

I have the following div where I use the attribute equalizer:

<div class="text-center" equalizer='group'>

However I only want that attribute equalizer to exist if the window width is > 400.

So I also use this code in my controller:

$scope.windowWidth = $window.innerWidth;

$window.onresize = function(event) {
        $timeout(function() {
          $scope.windowWidth = $window.innerWidth;
        });
};

Now I understand I can do something like:

equalizer="{{ windowWidth>400 ? 'group' : ''}}"

However the problem is whether or not I have a value in equalizer it is still applied - namely <div class="text-center" equalizer=''> works in the same as <div class="text-center" equalizer='group'>

So how do completely control whether that attribute is inserted or not?

TO ADD The only solution i have is duplicating the code and the using ng-if

so :

<div ng-if="windowWidth<400" class="text-centre">

and

<div ng-if="windowWidth>=400" class="text-center" equalizer='group'>

Thanks.

userMod2
  • 8,312
  • 13
  • 63
  • 115
  • Possible duplicate of [What is the best way to conditionally apply attributes in Angular?](http://stackoverflow.com/questions/15696416/what-is-the-best-way-to-conditionally-apply-attributes-in-angular) – Casey Jul 02 '16 at 22:12
  • @Casey not a duplicate - I have seen that answer: `ng-attr-class="{{someBoolean && 'class-when-true' || 'class-when-false' }}"` however my issue is I need to able to say `equalizer="group"` or not have it at all. – userMod2 Jul 02 '16 at 22:20
  • 3
    Why can't you just adjust what `equalizer` directive does internally? Also why not create `$scope.equalizer` and move the ternary to controller? – charlietfl Jul 02 '16 at 22:20
  • @userMod2 So use `ng-attr-equalizer` – Casey Jul 02 '16 at 23:07
  • That div can either be `
    ` or `
    ` - if I use `ng-attr-equalizer="{{windowWidth>400 && 'group'}}"` - then equalizer always appears either with `'group'` or as `''`
    – userMod2 Jul 02 '16 at 23:33

1 Answers1

0

I would create a resize directive that's updating a scope variable that you can check inside of your equalizer directive.

I'm not exactly sure what your equalizer directive is doing but something like in the demo below (or in this fiddle) should work.

In the demo I'm removing the equalizer directive for testing if the resize event is removed with the directive.

Adding a directive would look like the untested code below but I would do it like in the demo with ng-if:

var childScope = $scope.$new();
var directiveElement = angular.element('<equalizer></equalizer>');
$document.append($compile(directiveElement)(childScope));

(Here is a demo found with Google for adding directives dynamically.)

angular.module('demoApp', [])
    .controller('mainController', function($scope) {
        $scope.equalizerOptions = {
            group: true
        };
        $scope.removeEqualizer = function() {
            // just for testing if resize handler is removed
            var equalizer = angular.element(document).find('equalizer');
            //console.log(angular.element(document).find('equalizer').scope());
            equalizer.scope().$destroy();
            equalizer.remove();
        }
    })
    .directive('equalizer', equalizerDir)
    .directive('resize', resizeDir);

function resizeDir($window) {
    return {
        link: function(scope, element, attrs) {
            scope.window = {};

            function onResize(event) {
                //console.log('Resized', scope, element, event);
                scope.window.width = $window.innerWidth;
            }

            $window.onresize = function(evt) {
                //console.log('Resize');
                scope.$apply(onResize);
            };

            onResize(); //initial call

            scope.$on('$destroy', function() {
                //console.log('destroy dir');
                $window.onresize = undefined;
            });
        }
    };
}

function equalizerDir($timeout) {
    return {
        scope: {
            options: '=',
            width: '@'
        },
        template: '<div ng-if="width >= 400"><h2>equalizer with ng-if & resize dir</h2>' +
            '<p>{{options.group ? \'grouped\': \'not grouped\'}}</p></div>',
        link: function(scope, element, attrs) {
            /*scope.$watchCollection('options', function() {
             // would work but watch with ternary operator directly in markup is easier
             scope.text = scope.options.group ? 'grouped': 'not grouped';  
            });*/
        }
    };
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.7/angular.js"></script>
<div ng-app="demoApp" ng-controller="mainController">
  window width debugging: {{window.width}}
  <equalizer options="equalizerOptions" width="{{window.width}}" resize>
  </equalizer>

  <button ng-click="equalizerOptions.group = !equalizerOptions.group">
    toggle group
  </button>
  <button ng-click="removeEqualizer()">
    remove equalizer (test unbinding resize)
  </button>
</div>
AWolf
  • 8,770
  • 5
  • 33
  • 39