我正在制作一个可重复使用的Angular2组件,我希望用户能够指定一个模板字符串或templateUrl,然后该组件将通过属性或通过某种服务方法设置该组件.
// somewhere else in app
myService.setTemplateUrl('path/to/template.html');
// directive definition
function myDirective(myService) {
return {
template: function(element, attrs) {
return attrs.templateUrl || myService.getTemplateUrl();
}
// ...
};
}
Run Code Online (Sandbox Code Playgroud)
@Component({
selector: 'my-component',
template: '...' // cannot see `mySerivce` from here, nor access the element attributes
})
export class MyComponent {
constructor(private myService: MyService) {}
}
Run Code Online (Sandbox Code Playgroud)
虽然我的问题特别涉及如何实现动态模板,但更广泛的问题是是否可以从各种装饰器访问注入的依赖项实例.
所以我终于找到了一种方法来使用自定义模板来完成我想要的事情。
我认为实际问题的答案一定是否定的,可注入在装饰器中不可用。这是我对 Angular 2 组件生命周期的理解。
对于那些感兴趣的人,以下是我想出的用于实现用户定义的自定义模板的方法:
给定指令 ,SimpleTimer我们可以提供如下所示的自定义模板:
<!-- app.ts template -->
<div *simpleTimer="#timer=timerApi">
<div class="time">{{ timer.getTime() }}</div>
<div class="controls">
<button (click)="timer.toggle()">Toggle</button>
<button (click)="timer.reset()">Reset</button>
</div>
</div>
Run Code Online (Sandbox Code Playgroud)
然后像这样使用 TemplateRef 和 ViewContainerRef 可注入:
// SimpleTimer.ts
constructor(private templateRef: TemplateRef,
private viewContainer: ViewContainerRef,
private cdr: ChangeDetectorRef) {}
ngOnInit() {
// we need to detach the change detector initially, to prevent a
// "changed after checked" error.
this.cdr.detach();
}
ngAfterViewInit() {
let view = this.viewContainer.createEmbeddedView(this.templateRef);
let api = {
toggle: () => this.toggle(),
reset: () => this.reset(),
getTime: () => this.getTime()
}
view.setLocal('timerApi', api);
setTimeout(() => this.cdr.reattach());
}
Run Code Online (Sandbox Code Playgroud)
有关其工作方式和原因的演练,请参阅我就该主题撰写的这篇博客文章。
| 归档时间: |
|
| 查看次数: |
734 次 |
| 最近记录: |