Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to bind boolean values in angular directives?

I'd like to bind/set some boolean attributes to a directive. But I really don't know how to do this and to achieve the following behaviour.

Imagine that I want to set a flag to a structure, let's say that a list is collapsable or not. I have the following HTML code:

<list items="list.items" name="My list" collapsable="true"></list>

items are two-way binded, name is just an attribute

I'd like that collapsable attribute to be available in the list's $scope either by passing a value (true, false or whatever), either a two-way binding

<list items="list.items" name="{{list.name}}" collapsable="list.collapsed"></list>

I'm developing some UI components and I'd like to provide multiple way of interacting with them. Maybe, in time, some guys would like to know the state of that component, either is collapsed or not, by passing an object's property to the attribute.

Is there a way to achieve this? Please correct me if I missunderstood something or I'm wrong.

Thanks

like image 832
Chris X Avatar asked Aug 02 '13 10:08

Chris X


People also ask

Which angular structural directive takes a Boolean expression and makes an entire chunk of a Dom appear or disappear?

NgIf is the simplest structural directive and the easiest to understand. It takes a boolean expression and makes an entire chunk of the DOM appear or disappear. The ngIf directive doesn't hide elements with CSS.

How do you define a boolean variable in TypeScript?

Boolean values are supported by both JavaScript and TypeScript and stored as true/false values. TypeScript Boolean: let isPresent:boolean = true; Note that, the boolean Boolean is different from the lower case boolean type.

What are directives in Angular?

Directives are classes that add additional behavior to elements in your Angular applications. Use Angular's built-in directives to manage forms, lists, styles, and what users see.


3 Answers

You can configure your own 1-way databinding behavior for booleans like this:

link: function(scope, element, attrs) {

    attrs.$observe('collapsable', function() {

        scope.collapsable = scope.$eval(attrs.collabsable);
    });

}

Using $observe here means that your "watch" is only affected by the attribute changing and won't be affected if you were to directly change the $scope.collapsable inside of your directive.

like image 121
bingles Avatar answered Oct 20 '22 23:10

bingles


Create a scope on the directive that sets up bi-directional binding:

app.controller('ctrl', function($scope)
{
    $scope.list = {
        name: 'Test',
        collapsed: true,
        items: [1, 2, 3]
    };
});

app.directive('list', function()
{
    return {
        restrict: 'E',
        scope: {
            collapsed: '=',
            name: '=',
            items: '='
        },
        template:
            '<div>' +
                '{{name}} collapsed: {{collapsed}}' +
                '<div ng-show="!collapsed">' +
                    '<div ng-repeat="item in items">Item {{item}}</div>' +
                '</div>' +
                '<br><input type="button" ng-click="collapsed = !collapsed" value="Inside Toggle">' +
            '</div>'
    };
});

Then pass the options in as attributes:

<list items="list.items" name="list.name" collapsed="list.collapsed"></list>

http://jsfiddle.net/aaGhd/3/

like image 30
noj Avatar answered Oct 20 '22 23:10

noj


You can't pass strings true or false as the attribute value, and also support passing a scope property such as list.collapsed as the attribute value for two-way binding. You have to pick one way or the other.

This is because you can only specify one way to interpret the attribute's value in your directive when using an isolate scope.

I suppose you could use = in your diretive, and also check in your linking function if attrs.collapsable is set to true or false: if so, then you know a boolean value was passed, and if not, use the two-way data binding. But this is hacky.

like image 5
Mark Rajcok Avatar answered Oct 21 '22 01:10

Mark Rajcok