ng-show不适用于自定义指令

时间:2013-12-12 11:17:57

标签: angularjs

我刚刚开始使用AngularJS,并且想要创建一个自定义模板指令来创建“就地”可编辑表。这个想法是有类似的东西:

    <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>

然后还可以扩展它以指定templateUrl,例如<ng-template template-url="foo.html"></ng-template>

当我将ng-show指令应用于我的自定义指令时,它不起作用。这是我的指令的代码:

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

和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>

此外,当我查看生成的HTML时,我的自定义指令甚至没有出现在表中:

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

基本上我试图避免编写这样的代码(在每个ng-show元素上设置<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>

3 个答案:

答案 0 :(得分:3)

当我查看你的代码时,我发生了一些事情。

  1. ng-include为您的扩展ng-template提议提供了非常类似的功能。如果您要根据基础模型的状态加载视图,那么我认为这将是最佳选择。
  2. 如果您不打算从单独的视图文件加载模板,为什么不在您的td元素上使用ng-show(或ng-if / ng-switch,在大多数情况下我更喜欢)?< / LI>

    以下是使用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

答案 1 :(得分:2)

使用ng-repeat-startng-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 :(得分:1)

您的浏览器会在表格外部呈现“ng-template”,因为它不是tr的有效子项。即使已将replace设置为true,也需要在替换之前呈现该指令。

你可以看到它是因为这个表,因为这确实有效:

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

请参阅:Fiddle

这是您的浏览器所做的事情,因此您无法避免它。