jonhobbs
jonhobbs

Reputation: 27962

Angular isolate scope value can be set by "true" or empty

I have a custom angular directive which for the sake of brevity we'll just call map.

It has an isolate scope set up like this.

scope: {
    latitude: '=?',
    longitude: '=?',
    draggable: '=?'
},

I normally put something in my link function which sets scope values to be either what has been set in the attribute, or a default if nothing has been set so the devoloper can add draggable="false" if they want, otherwise we'll automatically default it to true, so in the link function I would have this.

$scope.draggable = angular.isDefined($scope.draggable) ? $scope.draggable : myDefaults.draggable;

The problem is that I want all of the following to be valid uses in html

<map draggable></map>
<map draggable="true"></map>
<map draggable="false"></map>

but the first line won't work because angular.isDefined() is false.

Should I check whether it is defined first and if it isn't then use something like attrs.draggable to see if the attribute exists before falling back on the default?

If so then there is a further complication because I need to put my code in the controller not the link function (because it needs to talk to child directives) and I don't have access to "attrs" or "element" from the controller.

Any help would be much appreciated.

Upvotes: 3

Views: 238

Answers (1)

Captain Delano
Captain Delano

Reputation: 466

If you don't want to use scope variables in your draggable attribute, just use the $attrs parameter in the directive's link function for all four of your use cases:

link: function ($scope, $element, $attrs) {
    if ("draggable" in $attrs) {
        $scope.draggable = $scope.draggable === "" || $attrs.draggable === "true";
    } else {
        $scope.draggable = myDefaults.draggable;
    }
}

Explanation: If the draggable attribute doesn't exist, it will not be in the $attrs object. If it exists but is not set, it will be equal to empty string. If it exists and is set, it will equal the string value you set it to: "true" or "false".

If you use $attrs, don't worry about assigning draggable via the scope property of your directive -- it will get overwritten.

Note, as mentioned above, this solution won't allow you to bind scope variables to the attribute. For that, you'll have to use the scope property on your directive.

For the curious, the link function.

Upvotes: 1

Related Questions