ng-click中的角度切换变量不起作用

时间:2014-12-11 11:37:34

标签: angularjs angularjs-directive

我有一个列出客户的表,对于也有客户列表的客户,我可以让用户点击表格行来显示该列表。 HTML看起来像这样:

        <tbody ng-repeat ="item in customers | clientSettingsFilter:customerId">
            <tr ng-class="{'row-hover': item.clientSettings.length>0}" ng-click="item.showClients=!item.showClients">
                <td><span ng-class="{true:'glyphicon glyphicon-chevron-down', false:'glyphicon glyphicon-chevron-right'}[item.showClients]"  ng-hide="item.clientSettings.length==0"></span></td>
                <td>{{item.id}}</td>
                <td>{{item.name}}</td>
                <td><button type="button" class="btn btn-default btn-xs" ng-click="go('/client-config/defaults/'+item.id)">Defaults</button></td>
            </tr>
            <tr ng-show="item.showClients">
                 ..... // client data

我所拥有的奇怪行为是:

如果我在客户数据集中未定义'showClients'属性,则一切都按预期工作,除了最初没有显示V形图标。单击一次后,它会显示,并且切换按预期工作。我认为这可能是因为ng-class正在寻找真或假,而undefined不满足其中任何一种。

如果我预先将showClients属性定义为true或false,则在页面加载时正确显示V形符号并且客户端列表正确显示,但切换不再起作用,就像ng-click要么没有做任何事情或者某些原因无法改变价值。我不确定如何调试这样的内联指令。

修改

根据请求,这是来自控制器的相关代码:

filter('clientSettingsFilter', function () {
    return function (customers, customerId) {
        var filtered = [];

        if (!customerId)
            return filtered;

        customerId = customerId.toLowerCase();

        angular.forEach(customers, function (item) {
            if (item.id.toLowerCase().indexOf(customerId) !== -1) {

                // format some text properties, omitted for brevity

                // if this line is uncommented, the ng-click does not work
                //item.showClients = false;
                filtered.push(item);
            }
        });

        return filtered;
    };
});

1 个答案:

答案 0 :(得分:3)

您在ng-class中使用的条件只会在值truefalse时添加内容,而不会在undefined时添加。

而是使用更详细的三元运算符:

ng-class="item.showClients ? 'glyphicon-chevron-down' : 'glyphicon-chevron-right'"

并且可以将班级glyphicon移动到普通的class属性:

class="glyphicon"

演示: http://plnkr.co/edit/bxgp4HyFkOygc0foxAKN?p=preview

您在过滤器中取消注释item.showClients = false;时看到的行为是由于摘要循环的工作原理。

如果item.showClientsfalse并且您单击tr,则会发生以下情况(稍微简化):

  1. ng-click中的表达式会执行,将item.showClients设为true
  2. 摘要循环将开始
  3. 过滤器将运行并再次将item.showClients设置为false
  4. 过滤器用于过滤,而不是用于修改。

    另请注意,当使用带有ng-repeat的过滤器时,它会触发每个摘要周期,并且由于每个摘要循环包含多个摘要周期(最少两个),因此保持过滤器简单或者它们会很糟糕很重要对绩效的影响。