如何有条件地将 div 包裹在 ng-content 周围
How to conditionally wrap a div around ng-content
取决于(布尔)class 变量的值我希望我的 ng-content
被包裹在 div 或不被包裹在 div(即 div 甚至不应该在 DOM 中)...最好的方法是什么?我有一个 Plunker 试图这样做,我认为这是最明显的方式,使用 ngIf .. 但它不起作用......它只显示一个布尔值的内容,而不显示另一个
请协助
谢谢!
http://plnkr.co/edit/omqLK0mKUIzqkkR3lQh8
@Component({
selector: 'my-component',
template: `
<div *ngIf="insideRedDiv" style="display: inline; border: 1px red solid">
<ng-content *ngIf="insideRedDiv" ></ng-content>
</div>
<ng-content *ngIf="!insideRedDiv"></ng-content>
`,
})
export class MyComponent {
insideRedDiv: boolean = true;
}
@Component({
template: `
<my-component> ... "Here is the Content" ... </my-component>
`
})
export class App {}
我检查了这个并发现了一个关于标签多重包含的未解决问题。这可以防止您在单个模板文件中定义多个标签。
这解释了为什么只有在您的 plunker 示例中删除另一个标签时内容才能正确显示。
您可以在此处查看未解决的问题:
https://github.com/angular/angular/issues/7795
Angular^4
作为解决方法,我可以为您提供以下解决方案:
<div *ngIf="insideRedDiv; else elseTpl" style="display: inline; border: 1px red solid">
<ng-container *ngTemplateOutlet="elseTpl"></ng-container>
</div>
<ng-template #elseTpl><ng-content></ng-content> </ng-template>
Angular < 4
在这里你可以创建专门的指令来做同样的事情:
<div *ngIf="insideRedDiv; else elseTpl" style="display: inline; border: 1px red solid">
<ng-container *ngTemplateOutlet="elseTpl"></ng-container>
</div>
<template #elseTpl><ng-content></ng-content></template>
ngIf4.ts
class NgIfContext { public $implicit: any = null; }
@Directive({ selector: '[ngIf4]' })
export class NgIf4 {
private context: NgIfContext = new NgIfContext();
private elseTemplateRef: TemplateRef<NgIfContext>;
private elseViewRef: EmbeddedViewRef<NgIfContext>;
private viewRef: EmbeddedViewRef<NgIfContext>;
constructor(private viewContainer: ViewContainerRef, private templateRef: TemplateRef<NgIfContext>) { }
@Input()
set ngIf4(condition: any) {
this.context.$implicit = condition;
this._updateView();
}
@Input()
set ngIf4Else(templateRef: TemplateRef<NgIfContext>) {
this.elseTemplateRef = templateRef;
this.elseViewRef = null;
this._updateView();
}
private _updateView() {
if (this.context.$implicit) {
this.viewContainer.clear();
this.elseViewRef = null;
if (this.templateRef) {
this.viewRef = this.viewContainer.createEmbeddedView(this.templateRef, this.context);
}
} else {
if (this.elseViewRef) return;
this.viewContainer.clear();
this.viewRef = null;
if (this.elseTemplateRef) {
this.elseViewRef = this.viewContainer.createEmbeddedView(this.elseTemplateRef, this.context);
}
}
}
}
请记住,您可以将所有这些逻辑放在单独的组件中! (基于 yurzui 回答):
import { Component, Input } from '@angular/core';
@Component({
selector: 'div-wrapper',
template: `
<div *ngIf="wrap; else unwrapped">
<ng-content *ngTemplateOutlet="unwrapped">
</ng-content>
</div>
<ng-template #unwrapped>
<ng-content>
</ng-content>
</ng-template>
`,
})
export class ConditionalDivComponent {
@Input()
public wrap = false;
}
然后你可以像这样使用它:
<div-wrapper [wrap]="'true'">
Hello world!
</div-wrapper>
取决于(布尔)class 变量的值我希望我的 ng-content
被包裹在 div 或不被包裹在 div(即 div 甚至不应该在 DOM 中)...最好的方法是什么?我有一个 Plunker 试图这样做,我认为这是最明显的方式,使用 ngIf .. 但它不起作用......它只显示一个布尔值的内容,而不显示另一个
请协助 谢谢!
http://plnkr.co/edit/omqLK0mKUIzqkkR3lQh8
@Component({
selector: 'my-component',
template: `
<div *ngIf="insideRedDiv" style="display: inline; border: 1px red solid">
<ng-content *ngIf="insideRedDiv" ></ng-content>
</div>
<ng-content *ngIf="!insideRedDiv"></ng-content>
`,
})
export class MyComponent {
insideRedDiv: boolean = true;
}
@Component({
template: `
<my-component> ... "Here is the Content" ... </my-component>
`
})
export class App {}
我检查了这个并发现了一个关于标签多重包含的未解决问题。这可以防止您在单个模板文件中定义多个标签。
这解释了为什么只有在您的 plunker 示例中删除另一个标签时内容才能正确显示。
您可以在此处查看未解决的问题: https://github.com/angular/angular/issues/7795
Angular^4
作为解决方法,我可以为您提供以下解决方案:
<div *ngIf="insideRedDiv; else elseTpl" style="display: inline; border: 1px red solid">
<ng-container *ngTemplateOutlet="elseTpl"></ng-container>
</div>
<ng-template #elseTpl><ng-content></ng-content> </ng-template>
Angular < 4
在这里你可以创建专门的指令来做同样的事情:
<div *ngIf="insideRedDiv; else elseTpl" style="display: inline; border: 1px red solid">
<ng-container *ngTemplateOutlet="elseTpl"></ng-container>
</div>
<template #elseTpl><ng-content></ng-content></template>
ngIf4.ts
class NgIfContext { public $implicit: any = null; }
@Directive({ selector: '[ngIf4]' })
export class NgIf4 {
private context: NgIfContext = new NgIfContext();
private elseTemplateRef: TemplateRef<NgIfContext>;
private elseViewRef: EmbeddedViewRef<NgIfContext>;
private viewRef: EmbeddedViewRef<NgIfContext>;
constructor(private viewContainer: ViewContainerRef, private templateRef: TemplateRef<NgIfContext>) { }
@Input()
set ngIf4(condition: any) {
this.context.$implicit = condition;
this._updateView();
}
@Input()
set ngIf4Else(templateRef: TemplateRef<NgIfContext>) {
this.elseTemplateRef = templateRef;
this.elseViewRef = null;
this._updateView();
}
private _updateView() {
if (this.context.$implicit) {
this.viewContainer.clear();
this.elseViewRef = null;
if (this.templateRef) {
this.viewRef = this.viewContainer.createEmbeddedView(this.templateRef, this.context);
}
} else {
if (this.elseViewRef) return;
this.viewContainer.clear();
this.viewRef = null;
if (this.elseTemplateRef) {
this.elseViewRef = this.viewContainer.createEmbeddedView(this.elseTemplateRef, this.context);
}
}
}
}
请记住,您可以将所有这些逻辑放在单独的组件中! (基于 yurzui 回答):
import { Component, Input } from '@angular/core';
@Component({
selector: 'div-wrapper',
template: `
<div *ngIf="wrap; else unwrapped">
<ng-content *ngTemplateOutlet="unwrapped">
</ng-content>
</div>
<ng-template #unwrapped>
<ng-content>
</ng-content>
</ng-template>
`,
})
export class ConditionalDivComponent {
@Input()
public wrap = false;
}
然后你可以像这样使用它:
<div-wrapper [wrap]="'true'">
Hello world!
</div-wrapper>