Ng-show does not work with custom directive

I was just starting to use AngularJS and wanted to create a custom template directive to create in-place editable tables. The idea would be:

    <tr ng-repeat="customer in model.customers">
        <ng-template ng-hide="customer === model.selectedCustomer"> <!-- display template-->
            <td>{{customer.name}}</td>
        </ng-template>
        <ng-template ng-show="customer === model.selectedCustomer"> <!-- edit template -->
            <td><input type="text" ng-model="customer.name"/></td>
        </ng-template>
    </tr>

Then it can also be extended to indicate the Url pattern, for example. <ng-template template-url="foo.html"></ng-template>

When I apply the directive ng-showto my custom directive, it does not work. Here is the code for my directive:

var demo = angular.module("demo", [])
.directive("ng-template", function() {
    return {
        restrict: "E",
        replace: true,
        transclude: true
    }
});

and HTML ( http://jsfiddle.net/benfosterdev/ASXyy/ ):

<div ng-app="demo">
    <table>
        <tr ng-repeat="name in ['jane', 'john', 'frank']">
            <ng-template ng-show="name !== 'frank'">
                <td>{{name}}</td>
            </ng-template>
        </tr>
    </table>
</div>

Also, when I look at the generated HTML, my custom directive doesn't even appear in the table:

<div ng-app="demo" class="ng-scope">
    <ng-template ng-show="name !== 'frank'" class="">
    </ng-template>
    <table>   
        <tbody>
          ...
        </tbody>
    </table>
</div>

Essentially, I'm trying to avoid writing such code (setting a directive ng-showfor each element <td>):

<table>
    <tr ng-repeat="customer in customers">
        <ng-template>
            <td ng-hide="isSelected">{{customer.name}}</td>
            <td ng-hide="isSelected">{{customer.age}}</td>
            <td ng-hide="isSelected"><button ng-click="edit(customer)"</td>
            <td ng-show="isSelected"><input type="text" ng-model="customer.name"/></td>
            <td ng-show="isSelected"><input type="text" ng-model="customer.age"/></td>
            <td ng-show="isSelected"><button ng-click="save(customer)"</td>
        </ng-template>
    </tr>
</table>
+4
3

.

  • ng-include ng-. , , , .
  • , ng-show ( ng-if/ng-switch, ) td-?

ng-include:

<table>
    <thead>
        <th>One</th>
        <th>Two</th>
        <th>Three</th>
        <th></th>
    </thead>
    <tbody>
        <tr ng-repeat="item in items" ng-include="getTemplate(item)"></tr>
    </tbody>
</table>

JSFiddle: http://jsfiddle.net/qQR6j/2.

+3

ng-repeat-start ng-repeat-end, <tr>.

<div ng-app="demo">
    <table ng-controller="Ctrl">
        <tr ng-repeat-start="name in ['jane', 'john', 'frank']" ng-hide="isSelected(name)">
            <td>{{name}} <button ng-click="select(name)">edit</button></td>
        </tr>
        <tr ng-repeat-end ng-show="isSelected(name)">
            <td>{{name}}!</td>
        </tr>
    </table>
</div>

javascript

var demo = angular.module("demo", []);

demo.controller("Ctrl",
function Ctrl($scope) {
    var selected;
    $scope.isSelected = function(name) {
        return selected === name;
    };
    $scope.select = function(name) {
        selected = name;
    };
});

: http://jsfiddle.net/6FtjG/1/

+2

Your browser displays "ng-template" outside the table because it is not a valid tr child. Even if you replaced with true, the directive must be displayed before it can be replaced.

You can see that this is because of the table, because it works:

 <div>
    <div ng-repeat="name in ['jane', 'john', 'frank']">
        <ng-template ng-show="name !== 'frank'">
            <div >{{name}}</div>
        </ng-template>            
    </div>
</div>

see fiddle

This is what your browser does, so you cannot avoid it.

+1
source

All Articles