Javascript AngularJS 模板中的条件逻辑
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/14077471/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Conditional logic in AngularJS template
提问by jonhobbs
I have an angular template which looks like this...
我有一个看起来像这样的角度模板......
<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>
I have set up a JSfiddleto show the data being bound.
我已经设置了一个 JSfiddle来显示被绑定的数据。
What I need to do is make the "from", "to" and "arrowTo" divs show conditionally, depending on the content of the data.
我需要做的是根据数据的内容有条件地显示“from”、“to”和“arrowTo”div。
The log is is this...
日志是这样的...
- If there is a "from" object in the data then show the "from" div and bind the data but don't show the "createdBy" div .
- If there is no "from" object but there is a "createdBy" object then show the "createdBy" div and bind the data.
- If there is a "to" object in the data then show the "arrowTo" div and bind it's data.
- 如果数据中有“from”对象,则显示“from” div 并绑定数据,但不显示“createdBy” div 。
- 如果没有“from”对象但有“createdBy”对象,则显示“createdBy”div并绑定数据。
- 如果数据中有“to”对象,则显示“arrowTo”div并绑定它的数据。
Or in plain English, if there is a from address, show it, otherwise show who created the record instead and if there is a to address then show that too.
或者用简单的英语,如果有发件人地址,则显示它,否则显示创建记录的人,如果有收件人地址,则也显示。
I have looked into using ng-switch but I think I'd have to add extra markup which would leave an empty div if there was no data. Plus I'd need to nest switch directives and I'm not sure if that would work.
我已经研究过使用 ng-switch,但我认为我必须添加额外的标记,如果没有数据,它会留下一个空的 div。另外,我需要嵌套 switch 指令,我不确定这是否可行。
Any ideas?
有任何想法吗?
UPDATE:
更新:
If I were to write my own directive (If I knew how!) then here is some pseudo code to show how I would want to use it...
如果我要编写自己的指令(如果我知道怎么做!),那么这里有一些伪代码来展示我想如何使用它...
<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>
Each of these would disappear if the function/expression evaluated to false.
如果函数/表达式的计算结果为假,这些中的每一个都会消失。
回答by Mark Rajcok
Angular 1.1.5 introduced the ng-ifdirective. That's the best solution for this particular problem. If you are using an older version of Angular, consider using angular-ui's ui-ifdirective.
Angular 1.1.5 引入了ng-if指令。这是解决此特定问题的最佳解决方案。如果您使用的是旧版本的 Angular,请考虑使用 angular-ui 的ui-if指令。
If you arrived here looking for answers to the general question of "conditional logic in templates" also consider:
如果您来到这里寻找“模板中的条件逻辑”这一一般问题的答案,还请考虑:
- 1.1.5 also introduced a ternary operator
- ng-switchcan be used to conditionally add/remove elements from the DOM
- see also How do I conditionally apply CSS styles in AngularJS?
- 1.1.5 还引入了三元运算符
- ng-switch可用于有条件地从 DOM 中添加/删除元素
- 另请参阅如何在 AngularJS 中有条件地应用 CSS 样式?
Original answer:
原答案:
Here is a not-so-great "ng-if" directive:
这是一个不太好的“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(' ')
}
}
}
});
that allows for this HTML syntax:
允许使用这种 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() is used to remove unneeded content from the DOM.
replaceWith() 用于从 DOM 中删除不需要的内容。
Also, as I mentioned on Google+, ng-stylecan probably be used to conditionally load background images, should you want to use ng-show instead of a custom directive. (For the benefit of other readers, Jon stated on Google+: "both methods use ng-show which I'm trying to avoid because it uses display:none and leaves extra markup in the DOM. This is a particular problem in this scenario because the hidden element will have a background image which will still be loaded in most browsers.").
See also How do I conditionally apply CSS styles in AngularJS?
此外,正如我在 Google+ 上提到的,如果您想使用 ng-show 而不是自定义指令,ng-style可能可用于有条件地加载背景图像。(为了其他读者的利益,Jon 在 Google+ 上说:“这两种方法都使用 ng-show,我试图避免它,因为它使用 display:none 并在 DOM 中留下额外的标记。这是这种情况下的一个特殊问题,因为隐藏元素将具有背景图像,该图像仍将在大多数浏览器中加载。”)。
另请参阅如何在 AngularJS 中有条件地应用 CSS 样式?
The angular-ui ui-ifdirective watches for changes to the if condition/expression. Mine doesn't. So, while my simple implementation will update the view correctly if the model changes such that it only affects the template output, it won't update the view correctly if the condition/expression answer changes.
的角度的UI的UI-如果指令手表更改如果条件/表达。我的没有。因此,虽然我的简单实现会在模型发生变化时正确更新视图,从而仅影响模板输出,但如果条件/表达式答案发生变化,则不会正确更新视图。
E.g., if the value of a from.name changes in the model, the view will update. But if you delete $scope.data.messages[0].from, the from name will be removed from the view, but the template will not be removed from the view because the if-condition/expression is not being watched.
例如,如果模型中 from.name 的值发生变化,视图将更新。但是如果你delete $scope.data.messages[0].from, from 名称将从视图中删除,但模板不会从视图中删除,因为 if-condition/expression 没有被监视。
回答by asgoth
You could use the ngSwitchdirective:
您可以使用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>
If you don't want the DOM to be loaded with empty divs, you need to create your custom directive using $http to load the (sub)templates and $compile to inject it in the DOM when a certain condition has reached.
如果您不希望使用空 div 加载 DOM,则需要使用 $http 创建自定义指令以加载(子)模板,并在达到特定条件时使用 $compile 将其注入 DOM。
This is just an (untested) example. It can and should be optimized:
这只是一个(未经测试的)示例。它可以而且应该被优化:
HTML:
HTML:
<conditional-template ng-model="element" template-url1="path/to/partial1" template-url2="path/to/partial2"></div>
Directive:
指示:
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()
}
};
});
回答by matko.kvesic
You can use ng-show on every div element in the loop. Is this what you've wanted: http://jsfiddle.net/pGwRu/2/?
您可以在循环中的每个 div 元素上使用 ng-show。这是您想要的:http: //jsfiddle.net/pGwRu/2/?
<div class="from" ng-show="message.from">From: {{message.from.name}}</div>

