Lu4
Lu4

Reputation: 15032

Directive with two template containers

I'm trying to create a "version" directive:

$scope.text = "Lorem ipsum";
$scope.target = ["a", "b", "c"];
<table>
    <version array="target">
        <one>
            <tr class="row">
                <td class="col">ONE {{version}}: {{ text }}</td>
            </tr>
        </one>
        <many>
            <tr class="row" ng-repeat="version in versions">
                <td class="col">MANY {{version}}: {{ text }}</td>
            </tr>
        </many>
    </version>
</table>

It acts pretty simple, it just substitutes one of the templates defined within one or many elements depending on the amount of elements fed to it. In our case it's called target. In case when array contains one element, directive uses template defined within one element, if more that it uses template defined in many element. Directive is also restricted to not producing redundant html elements, so that we don't end up with some strange divs inside table.

HERE: http://jsfiddle.net/0ckbz2n7/50/ (Does not support switching between one and many)

I have killed all day but reached some progress with this task, as you can see from jsFiddle url this is version #50 already and it's not the first fiddle that I'm trying to create from scratch, other than that I feel like I'm doing it wrong way, so maybe you guys who have more experience than I do can help me with finishing this task cuz I see no light in the end of the chamber

Upvotes: 0

Views: 48

Answers (1)

Wawy
Wawy

Reputation: 6269

I've simplified your code quite a bit. Is this what you want?

app.directive('version', function($compile) {
      var oneTemplate = '';
      var twoTemplate = '';
      return {
            restrict: 'E',
            scope: true,
            controller: function ($scope, $element, $attrs) {
                $scope.$watchCollection($attrs['track'], function(newVal, oldVal) {
                     var template;
                     $element.empty();
                     delete $scope.versions;
                     delete $scope.version;
                     if (newVal) {
                        if(newVal.length === 1) {
                            $scope.version = newVal[0];
                            template = angular.element(oneTemplate);
                        } else {
                            $scope.versions = newVal;
                            template = angular.element(twoTemplate)
                        }
                        $element.append(template);
                        $compile(template)($scope);
                     }
                });
            },
            compile: function(element, attr) {
                oneTemplate = element.find('one').html();
                twoTemplate = element.find('many').html();
            }
      };
  })

EDIT:

It should be $watchCollection instead of $watch, since you are watching an array.

Additionally if you don't want to create a directive, you could simply use ng-switch:

<div class="table" ng-switch="target.length" ng-init="version = target[0]; versions = target">
    <div class="row" ng-switch-when="1">
        <div class="col">ONE {{version}}: {{ text }}</div>
    </div>
    <div class="row" ng-switch-default="" ng-repeat="version in target">
        <div class="col">MANY {{version}}: {{ text }}</div>
    </div>
</div>

http://jsfiddle.net/0ckbz2n7/60/

Upvotes: 1

Related Questions