AngularJS模板中的条件逻辑

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

<div ng-repeat="message in data.messages" ng-class="message.type"> <div class="info"> <div class="type"></div> <div class="from">From Avatar</div> <div class="createdBy">Created By Avatar</div> <div class="arrowTo"> <div class="arrow"></div> <div class="to">To Avatar</div> </div> <div class="date"> <div class="day">25</div> <div class="month">Dec</div> </div> </div> <div class="main"> <div class="content"> <div class="heading2">{{message.title}}</div> <div ng-bind-html="message.content"></div> </div> </div> <br /> <hr /> <br /> </div> 

我build立了一个JSfiddle来显示绑定的数据。

我需要做的是根据数据的内容,有条件地制作“从”,“到”和“箭头到”div。

日志是这个…

  • 如果数据中有“from”对象,则显示“from”div并绑定数据,但不显示“createdBy”div。
  • 如果没有“from”对象,但有一个“createdBy”对象,则显示“createdBy”div并绑定数据。
  • 如果数据中有“to”对象,则显示“arrowTo”div并绑定数据。

或者用简单的英语,如果有一个地址,显示它,否则显示谁创build了这个logging,如果有一个地址,那么也显示出来。

我已经研究过使用ng-switch,但是我想我不得不添加额外的标记,如果没有数据,会留下一个空的div。 另外我需要嵌套开关指令,我不知道这是否会工作。

有任何想法吗?

更新:

如果我写我自己的指令(如果我知道如何!),那么这里是一些伪代码,以显示我将如何使用它…

 <div ng-if="showFrom()"> From Template Goes Here </div> <div ng-if="showCreatedBy()"> CreatedBy Template Goes Here </div> <div ng-if="showTo()"> To Template Goes Here </div> 

如果函数/expression式计算结果为false,则每个函数都会消失。

Angular 1.1.5引入了ng-if指令。 这是解决这个问题的最佳解决scheme。 如果您使用的是旧版本的Angular,请考虑使用angular-ui的ui-if指令。

如果你到达这里寻找“模板中的条件逻辑”一般问题的答案,也可以考虑:

  • 1.1.5还介绍了一个三元运算符
  • ng-switch可用于有条件地添加/删除DOM中的元素
  • 另请参阅如何在AngularJS中有条件地应用CSS样式?

原始答案:

这是一个不太好的“ng-if”指令:

 myApp.directive('ngIf', function() { return { link: function(scope, element, attrs) { if(scope.$eval(attrs.ngIf)) { // remove '<div ng-if...></div>' element.replaceWith(element.children()) } else { element.replaceWith(' ') } } } }); 

这允许这个HTML语法:

 <div ng-repeat="message in data.messages" ng-class="message.type"> <hr> <div ng-if="showFrom(message)"> <div>From: {{message.from.name}}</div> </div> <div ng-if="showCreatedBy(message)"> <div>Created by: {{message.createdBy.name}}</div> </div> <div ng-if="showTo(message)"> <div>To: {{message.to.name}}</div> </div> </div> 

小提琴 。

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

另外,正如我在Google+上所提到的,如果您想使用ng-show而不是自定义指令,那么ng-style可以用来有条件地加载背景图片。 Jon为了其他读者的利益,在Google+上说:“这两种方法都使用ng-show,我试图避免,因为它使用display:none,并在DOM中留下额外的标记,这是这个场景中的一个特殊问题,隐藏的元素将有一个背景图像,仍然会在大多数浏览器中加载“)。
另请参见如何在AngularJS中有条件地应用CSS样式?

angular-ui ui-if指令监视if条件/expression式的变化。 我的不是。 所以,虽然我的简单实现将正确地更新视图,如果模型更改,只会影响模板输出,它将不会正确更新视图如果条件/expression式答案更改。

例如,如果from.name的值在模型中更改,则视图将更新。 但是,如果delete $scope.data.messages[0].from ,那么将从视图中删除from名称,但是不会从视图中删除该模板,因为if-condition / expression不被监视。

你可以使用ngSwitch指令:

  <div ng-switch on="selection" > <div ng-switch-when="settings">Settings Div</div> <span ng-switch-when="home">Home Span</span> <span ng-switch-default>default</span> </div> 

如果你不希望DOM被加载为空的div,你需要使用$ http来创build自定义指令来加载(子)模板和$ compile,以便在达到特定条件时将其注入到DOM中。

这只是一个(未经testing)的例子。 它可以而且应该被优化:

HTML:

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

指示:

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

 <div class="from" ng-show="message.from">From: {{message.from.name}}</div>