根据 angular 中的 DOM 状态实例化嵌入的组件 2
Instantiate transcluded components depending on their DOM state in angular 2
常用菜单使用案例
<menu>
<menu-item1></menu-item1>
<menu-item2></menu-item2>
<menu-item3></menu-item3>
</menu>
菜单模板
<div *ngIf="open$ | async">
<ng-content></ng-content>
</div>
我很惊讶地听到所有 menu-item*
组件( 及其所有子组件 )将被实例化,尽管它们存在于 DOM 和 [=15] =] 组件 *ngIf
状态。即使从未打开菜单,它们的 OnInit
和 AfterViewInit
钩子也会被调用,并且 OnDestroy
永远不会触发,尽管确实从 DOM 中添加 - 删除。这是一个关于此 https://github.com/angular/angular/issues/13921 (there is a plnkr with example) and an issue to angular documentation https://github.com/angular/angular.io/issues/3099.
的已关闭问题
但这个问题仍然存在 - 我怎样才能使菜单项仅在菜单打开时实例化并在关闭时正确销毁?所有挂钩都应仅在与真实 DOM 状态相关时触发。
更新Angular5
ngOutletContext
已重命名为 ngTemplateOutletContext
另见 https://github.com/angular/angular/blob/master/CHANGELOG.md#500-beta5-2017-08-29
原创
您可以使用
<menu>
<template>
<menu-item1></menu-item1>
<menu-item2></menu-item2>
<menu-item3></menu-item3>
<template>
</menu>
@Component({
selector: 'menu',
template: `
<div *ngIf="open$ | async">
<template [ngTemplateOutlet]="templateRef"></template>
</div>
`
})
class MenuComponent {
@ContentChild(TemplateRef) templateRef:TemplateRef;
}
您还可以将上下文传递给 ngTemplateOutlet
(有一些答案显示了如何做到这一点,我没有时间只是不去查找它们)
这是一个使用 ngTemplateOutlet 的例子
import {Component, NgModule} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
@Component({
selector: 'my-app',
template: `
<template #templateRef let-label="label" let-url="url">
<div><a href="{{url}}">{{label}}</a></div>
</template>
<div [ngTemplateOutlet]="templateRef" [ngOutletContext]="menu[0]"></div>
<div [ngTemplateOutlet]="templateRef" [ngOutletContext]="menu[1]"></div>
`
})
export class App {
menu:any = [{
"id": 1,
"label": "AngularJS",
"url": "http:\/\/www.learn-angular.fr\/angularJS"
}, {
"id": 2,
"label": "Angular",
"url": "http:\/\/www.learn-angular.fr\/angular"
}];
constructor() {}
}
常用菜单使用案例
<menu>
<menu-item1></menu-item1>
<menu-item2></menu-item2>
<menu-item3></menu-item3>
</menu>
菜单模板
<div *ngIf="open$ | async">
<ng-content></ng-content>
</div>
我很惊讶地听到所有 menu-item*
组件( 及其所有子组件 )将被实例化,尽管它们存在于 DOM 和 [=15] =] 组件 *ngIf
状态。即使从未打开菜单,它们的 OnInit
和 AfterViewInit
钩子也会被调用,并且 OnDestroy
永远不会触发,尽管确实从 DOM 中添加 - 删除。这是一个关于此 https://github.com/angular/angular/issues/13921 (there is a plnkr with example) and an issue to angular documentation https://github.com/angular/angular.io/issues/3099.
但这个问题仍然存在 - 我怎样才能使菜单项仅在菜单打开时实例化并在关闭时正确销毁?所有挂钩都应仅在与真实 DOM 状态相关时触发。
更新Angular5
ngOutletContext
已重命名为 ngTemplateOutletContext
另见 https://github.com/angular/angular/blob/master/CHANGELOG.md#500-beta5-2017-08-29
原创
您可以使用
<menu>
<template>
<menu-item1></menu-item1>
<menu-item2></menu-item2>
<menu-item3></menu-item3>
<template>
</menu>
@Component({
selector: 'menu',
template: `
<div *ngIf="open$ | async">
<template [ngTemplateOutlet]="templateRef"></template>
</div>
`
})
class MenuComponent {
@ContentChild(TemplateRef) templateRef:TemplateRef;
}
您还可以将上下文传递给 ngTemplateOutlet
(有一些答案显示了如何做到这一点,我没有时间只是不去查找它们)
这是一个使用 ngTemplateOutlet 的例子
import {Component, NgModule} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'
@Component({
selector: 'my-app',
template: `
<template #templateRef let-label="label" let-url="url">
<div><a href="{{url}}">{{label}}</a></div>
</template>
<div [ngTemplateOutlet]="templateRef" [ngOutletContext]="menu[0]"></div>
<div [ngTemplateOutlet]="templateRef" [ngOutletContext]="menu[1]"></div>
`
})
export class App {
menu:any = [{
"id": 1,
"label": "AngularJS",
"url": "http:\/\/www.learn-angular.fr\/angularJS"
}, {
"id": 2,
"label": "Angular",
"url": "http:\/\/www.learn-angular.fr\/angular"
}];
constructor() {}
}