Playground for creating stateless Web applications with HTML5, CSS, JavaScript and PrimeUI on the client side and Java EE 6/7 with the JAX RS module that does the communication in JSON format on the server side.

Saturday, 6 April 2013

AngularJS directives: Using $watch

Introduction

In the previous blog text, we switched from the compile to the link function of the directive. This allowed us to use the scope object and have access to model values. The downside of it, our AngularJS expressions in the title attribute aren’t picked up anymore.
Nevertheless, we continue this path as it will allow us to programaticly collapse and expand the panel contents.

$watch

The scope object has a very usefull function, $watch. It allows us to add a watch function and react on it when the value changes. It is the programmatic way of defining an AngularJS expression.

scope.$watch(attrs.title, function (title) {

myPanel.setTitle(title);

})

The above is all that is needed to watch for a change and call the, newly created, title() function in the myPanel object. Using the above form, we can only monitor the changes in a simple expression like this

<divmy-dir6="panelOptions"title="panelTitle">

Where panelTitle is defined in the scope object.

$scope.panelTitle = 'Change me';

The more complex constructions like the one we had previously (title: {{panelTitle}}) can also be supported but requires a little bit more work. For those that are interested in it, I used it in the AngularPrime panel widget and involves the use of the $interpolate service. You can have a look at the code if you need that kind of functionality.

To be complete, this is then the title() function to change the title of the panel header.

setTitle: function(titleValue) {

this.titleSpan.html(titleValue);

}

Programmatic collapse

The programmatic collapse can be programmed in a similar way. We define a collapsed value within the scope as follows

$scope.panelOptions = {

collapsed : false

};

This can be manipulated in JavaScript in anyway we like and we are familiar with. And the change can be watched in a similar way as we did with the title attribute.

scope.$watch(attrs.myDir6 + '.collapsed', function (value) {

if (value === false) {

myPanel.show(element);

} else {

myPanel.hide(element);

}

});

As you can see, we are able to define the string expressions ourself which needs to be watched.
The end result is that we can define other elements, like buttons, that manipulate the value of collapsed and as a result, the panel contents can be collapsed or exapnded depending on the value we set.

The complete code can be found in the example 6 of the code on github.

Conclusion

By using the link function, we have to resort to the AngularJS function $watch to restore the functionality we had previously. But it opened a new way of integration paths. We can react on a simple change of a value and let it result in a visual effect on the screen.