Building Advanced Directives
ng-click="isOpen=!isOpen">{{heading}}</a>
</div>
<div class="accordion-body" ng-show="isOpen">
<div class="accordion-inner" ng-transclude></div>
</div>
</div>
We transclude the original child elements of the directive into the body of the
template. The template references isOpen and heading, on the current scope. We
want to have complete control over these values so that the accordion-group
directive will have an isolated scope.
In the tests, we set up an accordion and some accordion-group directives and
then check that they open and close correctly. Here is an example of the unit tests:
describe('accordion-group', function () {
var scope, element, groups;
beforeEach(inject(function($rootScope, $compile) {
scope = $rootScope;
var tpl =
"<accordion>" +
"<accordion-group heading='title 1'>Content 1</accordion-group>" +
"<accordion-group heading='title 2'>Content 2</accordion-group>" +
"</accordion>";
$compile(tpl)(scope);
scope.$digest();
groups = element.find('.accordion-group');
});
...
it('should change selected element on click', function () {
groups.eq(0).find('a').click();
expect(findGroupBody(0).scope().isOpen).toBe(true);
groups.eq(1).find('a').click();
expect(groups.eq(0).scope().isOpen).toBe(false);
expect(groups.eq(1).scope().isOpen).toBe(true);
});
...
});
We trigger a click event on groups and check that isOpen is false on the scope of
the other groups.
The implementation of the directive is fairly straightforward:
myModule.directive('accordionGroup', function() {
return {
require:'^accordion',