关于javascript:AngularJS模板中的条件逻辑

Conditional logic in AngularJS template

我有一个角度模板,看起来像这样…

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
        From Avatar
        Created By Avatar
       
           
            To Avatar
       
       
            25
            Dec
       
   

   
       
            {{message.title}}
           
       

   

    <br />
    <hr />
    <br />

我已经设置了一个JSfiddle来显示绑定的数据。

我需要做的是根据数据的内容,使"From"、"To"和"Arrowto"分隔符有条件地显示出来。

日志是这样的…

  • 如果数据中有"From"对象,则显示"From"DIV并绑定数据,但不显示"CreatedBy"DIV。
  • 如果没有"from"对象,但有"createdby"对象,则显示"createdby"DIV并绑定数据。
  • 如果数据中有"to"对象,则显示"arrowto"DIV并绑定其数据。

或者用简单的英语,如果有"发件人"地址,则显示它,否则显示创建记录的人,如果有"收件人"地址,则也显示该地址。

我已经研究过使用ng开关,但是我想我必须添加额外的标记,如果没有数据,这个标记会留下一个空的DIV。另外,我需要嵌套开关指令,我不确定这是否有效。

有什么想法吗?

更新:

如果我要写自己的指令(如果我知道怎么写的话!)下面是一些伪代码来说明我想如何使用它…

1
2
3
4
5
6
7
    From Template Goes Here


    CreatedBy Template Goes Here


    To Template Goes Here

如果函数/表达式的计算结果为false,则所有这些都将消失。


角度1.1.5引入了ng if指令。这是解决这个特定问题的最佳方案。如果您使用的是旧版本的Angular,请考虑使用Angular UI的ui if指令。

如果您来到这里寻找"模板中的条件逻辑"的一般问题的答案,请考虑:

  • 1.1.5还引入了三元运算符
  • ng开关可用于在DOM中有条件地添加/删除元素。
  • 另请参见如何在AngularJS中有条件地应用CSS样式?

原始答案:

这里有一个不太好的"ng-if"指令:

1
2
3
4
5
6
7
8
9
10
11
12
myApp.directive('ngIf', function() {
    return {
        link: function(scope, element, attrs) {
            if(scope.$eval(attrs.ngIf)) {
                // remove ''
                element.replaceWith(element.children())
            } else {
                element.replaceWith(' ')
            }
        }
    }
});

允许这种HTML语法:

1
2
3
4
5
6
7
       From: {{message.from.name}}
       
   
      Created by: {{message.createdBy.name}}
       
   
      To: {{message.to.name}}

小提琴。

replaceWith()用于从DOM中删除不需要的内容。

另外,正如我在google+上提到的,ng样式可能用于有条件地加载背景图像,如果您希望使用ng show而不是自定义指令。(为了其他读者的利益,jon在google+上说:"这两种方法都使用了ng-show,这是我试图避免的,因为它使用了display:none,并在dom中留下了额外的标记。"在这种情况下,这是一个特别的问题,因为隐藏元素将有一个背景图像,在大多数浏览器中仍然会加载它。")。另请参见如何在AngularJS中有条件地应用CSS样式?

angular ui ui if指令监视if条件/表达式的更改。我的没有。因此,虽然我的简单实现会正确地更新视图,但如果模型发生更改,使其只影响模板输出,但如果条件/表达式应答发生更改,则不会正确地更新视图。

例如,如果模型中from.name的值发生更改,则视图将更新。但是,如果您是delete $scope.data.messages[0].from,则将从视图中删除源名称,但不会从视图中删除模板,因为不会监视if条件/表达式。


您可以使用ngswitch指令:

1
2
3
    Settings Div
    <span ng-switch-when="home">Home Span</span>
    <span ng-switch-default>default</span>

如果不希望用空的div加载dom,则需要使用$http来创建自定义指令来加载(子)模板,$compile在达到某个条件时将其注入dom。

这只是一个(未测试的)示例。它可以也应该优化:

HTML:

1
<conditional-template ng-model="element" template-url1="path/to/partial1" template-url2="path/to/partial2">

指令:

1
2
3
4
5
6
7
8
9
10
11
12
app.directive('conditionalTemplate', function($http, $compile) {
   return {
      restrict: 'E',
      require: '^ngModel',
      link: function(sope, element, attrs, ctrl) {
        // get template with $http
        // check model via ctrl.$viewValue
        // compile with $compile
        // replace element with element.replaceWith()
      }
   };
});


您可以在循环中的每个DIV元素上使用ng show。这就是你想要的:http://jsfiddle.net/pgwru/2/?

1
From: {{message.from.name}}