我们构建一个类似仪表板的界面,并经常接收带有可选字段的通用对象,例如下面的event
对象。加载模板时可能未定义event
,它可能有也可能没有daysRemaining ?: number
参数;如果已设置,则可能为0
。
为确保在上述方案中实际打印0
值,我们使用以下模式:
<div *ngIf="event?.daysRemaining?.toString().length > 0">
{{event.daysRemaining}} days
</div>
(.toString()
是必要的,因为属性'长度'在类型'number'上不存在。)
我们的对象树可以比上面的例子更深入 。我们可以在<ng-container>
的{{1}}中包含父树的常见内容,但我们很少能这样做。
必须有更优雅的方式来执行此操作,尤其是需要在几乎所有可选*ngIf
上调用.toString()
。
这似乎更有效:
number
但缺点是,如果我们需要选择性地向<div>
{{event?.daysRemaining + ' days'}}
</div>
添加内容(<div>
时为color: red
),我们仍然需要进行所有检查。
答案 0 :(得分:1)
您可以使用方法检查组件中的条件。
<div *ngIf="daysRemaining(event)">
{{event.daysRemaining}} days
</div>
Typescript方法将为
daysRemaining(event){
if(event && event.daysRemaining.toString().length > 0){
return true;
} else {
return false;
}
}
答案 1 :(得分:1)
在组件类中,我会使用类似的东西:
get daysRemaining(){
return this.event && (this.event.daysRemaining || this.event.daysRemaining === 0) ?
this.event.daysRemaining + ' days' : undefined;
}
并在模板中:
<div>
{{daysRemaining}}
</div>
如果您认为migth正在做这么多,您可以创建一个管道:
import { Pipe, PipeTransform } from '@angular/core';
@Pipe({name: 'printIfDefined'})
export class PrintIfDefinedPipe implements PipeTransform {
transform(value:number, suffix?:string): number {
let suffix = (suffix ? ' ' + suffix : '');
return (value || value === 0) ? value + suffix : undefined;
}
}
并在模板中:
<div>
{{event?.daysRemaining | printIfDefined: 'days' }}
</div>
在两种选择中,div仍然在de DOM上注入,因为它没有内容它不应该影响你的应用程序(除非你有css具有固定宽度或类似的东西)。
如果DOM空间占用困扰你,另一个替代migth是一个指令:
import { Directive, ElementRef, HostListener, Input } from '@angular/core';
@Directive({
selector: '[print-if-defined]'
})
export class PrintIfDefinedDirective {
constructor(private el: ElementRef) { }
@Input('suffix')
suffix:string;
@Input('value')
set value(nm:number) {
this.el.nativeElement.style.display = nm || nm === 0 ? "" : "none";
this.el.nativeElement.textContent = nm + (this.suffix ? ' ' + this.suffix : '');
}
}
并像
一样使用它<div print-if-defined [value]="event?.daysRemaining" suffix="days"></div>
你可以看到所有这些都在运行: https://plnkr.co/edit/gFeKJilYGdt5ttENjKUG?p=preview