AngularJS Definition List Directive

by Warspawn

HTML

<div ng-app="myApp" ng-controller="myCtrl">
    <h2>Definition Lists</h2>
    <span def-list="term, def in items | limitTo:3"></span>
    <button ng-click="update()">Update</button>
</div>

CSS

dl {padding:8px;}
dt {font-weight:bold;}
dd {padding-left: 8px;}

JavaScript

angular.module('myApp', []).controller('myCtrl', function($scope, $log) {
    $scope.items = [
        {
        term: 'Word',
        def: ['W at the beginning, D at the end, OR in the middle', 'Word Riggs']},
    {
        term: 'Hat',
        def: ['goes on your head']}
                   ];

    $scope.update = function() {
        $log.log("update");
        $scope.items = [
            {
            term: ['Foo', 'Bar'],
            def: ['Some nonsense words.']},
        {
            term: 'Word',
            def: ['W at the beginning, D at the end, OR in the middle', 'Word Riggs']},
        {
            term: 'Hat',
            def: ['goes on your head']}
        ];
    };
}).directive('defList', function($log, $compile, $parse) {
    return {
        replace: true,
        template: '<dl></dl>',
        link: function(scope, el, attrs) {
            var match = attrs.defList.match(/^\s*(.+)\s+in\s+(.*)\s*$/),
                tmpl = '<dt ng-repeat="term in terms">{{ term }}</dt><dd ng-repeat="def in defs">{{ def }}</dd>',
                collection = scope.$eval(match[2]),
                props = match[1].split(',');

            $log.log("defList directive, match:", match, "collection: ", collection, "props: ", props);

            var renderList = function(collection) {
                el.html(''); // clear old
                angular.forEach(collection, function(value, index) {
                    var t = angular.element(tmpl),
                        s = scope.$new(),
                        terms = value[props[0].trim()],
                        defs = value[props[1].trim()];

                    s.terms = angular.isArray(terms) ? terms : [terms];
                    s.defs = angular.isArray(defs) ? defs : [defs];

                    //$log.log("renderList ITEM: ", value, terms, defs);
                    el.append(t);
                    $compile(t)(s);
                });
            };

            renderList(collection);

           ...