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>