
[英]How do i display a Angular component inside another Angular component
[英]How do I create my own component lifecycle callback associated with another component in Angular?
我很难掌握 Angular 和 Promises 的窍门。 我正在尝试为角度数据表创建另一层包装器以添加一些通用自定义,然后让基础组件知道它已完成并允许访问该实例变量。 非常类似于 ngAfterViewInit,但“parentNgAfterViewInit”——我将其命名为 dtAfterInit。
app.component.ts (1 级/基础)
export class AppComponent implements OnInit, OnDestroy {
ngOnInit(): void {
this.http.get<any[]>("./assets/data/data.json").subscribe(datas => {
this.datas = datas;
this.dtTrigger.next();
});
});
}
ngOnDestroy(): void {
this.dtTrigger.unsubscribe();
}
dtAfterInit(dtInstance: DataTables.Api): void {
//@todo
}
}
app.component.html (1级/基地)
<datatable
[dtOptions]="dtOptions"
[dtTrigger]="dtTrigger"
paginationLength="true"
filter="true"
tableClass="table table-striped table-bordered table-hover"
width="100%"
>
<thead>
<!-- THEAD -->
</thead>
<tbody>
<!-- TBODY -->
</tbody>
</datatable>
datatable.component.ts (2级)
@Component({
selector: "datatable",
template: `
<table
datatable
[dtOptions]="dtOptions"
[dtTrigger]="dtTrigger2"
class="dataTable responsive {{ tableClass }}"
width="{{ width }}"
>
<ng-content></ng-content>
</table>
`
})
export class DatatableComponent implements OnInit, OnDestroy {
@ViewChild(DataTableDirective, { static: false })
datatableElement: DataTableDirective;
/** <DataTables Inputs> */
@Input() public dtOptions: DataTables.Settings = {};
@Input() public dtTrigger: Subject<any> = new Subject();
/** </DataTables Inputs> */
private dtTrigger2: Subject<any> = new Subject();
ngOnInit(): void {
if (this.dtTrigger) {
this.dtTrigger.subscribe(() => {
this.dtTrigger2.next();
this.datatableElement.dtInstance.then((dtInstance: DataTables.Api) => {
//window["test"] = dtInstance; //Give this instance over to the AppComponent
//@todo AppComponent.dtAfterInit(dtInstance)
});
});
}
}
ngOnDestroy(): void {
this.dtTrigger2.unsubscribe();
}
/** Attempt #2, but
* This doesn't quite work because it isn't guaranteed that (the HTTP request is completed prior to this)
* this.dtTrigger.next() got called yet, so this.datatableElement.dtInstance could be null
ngAfterViewInit(): void {
this.datatableElement.dtInstance.then((dtInstance: DataTables.Api) => {
window["test"] = dtInstance; //Give this instance over to the AppComponent
//@todo AppComponent.dtAfterInit(dtInstance)
});
} */
在@todo 中,dtInstance 已成功初始化。 现在我想将此变量从DatatableComponent传递回AppComponent ,并让它从这个时间点(在它被初始化之后)执行任何额外的单个组件级事件绑定,或者只是为了能够直接访问数据表 API .
在上面的例子中,我试图创建两个 / 嵌套的主题,这样当 AppComponent 下一次触发时,它会触发 DatatableComponent 触发器,然后触发 DataTableDirective(角度数据表包装库),所以我们可以做我们的 dtAfterInit 回调这里。 但我想这很丑陋而且不是很“Angular”,此外,我使用window["test"] = dtInstance
使 dtInstance 成为全局变量,以便 AppComponent 可以访问它以更好地说明我正在尝试做的事情.
是否有事件可以保证 http.get() 完成,因此 dt 也被初始化? 我已经尝试过 ngAfterViewInit,但我不相信这有效,因为 this.dtTrigger.next() 尚未触发,所以 dtInstance 是 null。 这里最好的方法是直接修改 angular-datatables 包装器吗?
angular-datatables.directive.ts (3 级)
@Directive({
selector: '[datatable]'
})
export class DataTableDirective implements OnDestroy, OnInit {
dtInstance: Promise<DataTables.Api>;
ngOnInit(): void {
if (this.dtTrigger) {
this.dtTrigger.subscribe(() => {
this.displayTable();
});
} else {
this.displayTable();
}
}
private displayTable(): void {
this.dtInstance = new Promise((resolve, reject) => {
Promise.resolve(this.dtOptions).then(dtOptions => {
// Using setTimeout as a "hack" to be "part" of NgZone
setTimeout(() => {
this.dt = $(this.el.nativeElement).DataTable(dtOptions);
resolve(this.dt);
});
});
});
/* @attempt#3, I'm thinking maybe directly modifying this library be the best way? If there isn't an event I can use, or to avoid having the two trigger to just one
ex. Promise.resolve(this.dtInstance).then(
//@todo AppComponent.dtAfterInit(dtInstance)
);
*/
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.