1
votes

I'm trying to create a directive that will disable all the input elements inside of the container, but I'm having trouble with the attribute. This is what I've got for the directive

Directive

angular.module('common')
    .directive('bdDisabled', [function () {
            return {
                restrict: 'A',
                scope: {
                    bdDisabled: '='
                },
                link: function (scope, element, attrs) {
                    attrs.$observe('bdDisabled', function(newValue, oldValue) {
                        if (newValue !== oldValue) {
                            if (newValue) {
                                element.find('input, select, button, submit, textarea').prop('disabled', 'disabled');
                            } else {
                                element.find('input, select, button, submit, textarea').removeProp('disabled');
                            }

                        }
                    });
                }
            };
        }
    ]);

This is how I want to use it:

<div class="cg-content cg-shadow" bd-disabled="isLoading">

The problem is that the attribute value is the string isLoading and not the value.

If I wrap it in braces it breaks and I get an error in the console. If I wrap it in braces and change the scope to '@' instead of '=', it works. But it sends the string "true" or "false", not a boolean value.

Where am I going wrong?

3
What happens if you switch attrs.$observe with scope.$watch ? - Omri Aharon
I'll give it a try, hold on - Smeegs
using @ is for passing one way binding string. You may parse it to boolean, otherwise pass it as =, which will be two way binding object - dannielum
@OmriAharon, that did it. Thanks. Please suggest it as an answer and I'll accept it. - Smeegs

3 Answers

1
votes

As I suggested in the comment, I'd switch the attrs.$observe with scope.$watch. On a personal preference, I'd also use the function expression instead of a string, since if you're using typescript for instance (or will use) you'll be notified if the property changes, where a string will probably remain as it is:

scope.$watch(function () {
      return scope.bdDisabled;
      }, 
      function (newVal, oldVal) {
          ...
      }
);
-1
votes

You don't have to use observe with '='. See the following link for details, I believe it is much more robust than the docs.

What is the difference between '@' and '=' in directive scope in AngularJS?

As far as your code goes, I would double check the isLoading variable to make sure it is a boolean.

-1
votes

When you changed you scope definition from "=" to "@", you just want to pass the as a String, not the Two-Way-Bind mode. Sure, you can convert that to true indeed, like:

var myBool = Boolean("false"); // === true

var myBool = Boolean("true"); // === true

But be careful with that because any string can be consider as true like:

var myBool = Boolean("foo"); // === true