我正在尝试创建一个泛型指令,该指令将采用类类型进行规则验证,并且根据类中的规则,该指令将显示或隐藏元素。
这是我迄今为止的尝试。
PLUNKER演示
myIf-Directive.ts
@Directive({
selector: '[myIf]'
})
export class MyIfDirective {
constructor(private _viewContainer: ViewContainerRef,
private _template: TemplateRef<Object>)
{ }
@Input() set myIf(rule: string) {
//rule class type will come as string
//how can I use string token to get dependency from injector?
//currently harcoded
//will the injector create new instance or pass on instance from parent?
let injector = ReflectiveInjector.resolveAndCreate([AdminOnly]);
let adminOnly : IRule = injector.get(AdminOnly);
let show = adminOnly.shouldShowElement();
show ? this.showItem() : this.hideItem();
}
private showItem() {
this._viewContainer.createEmbeddedView(this._template);
}
private hideItem() {
this._viewContainer.clear();
}
}
应用-component.ts
@Component({
selector: 'my-app',
template: `
<div *myIf="'AdminOnly'">
<h2>Hello {{name}}</h2>
</div>
`,
})
export class App {
name:string;
constructor() {
this.name = 'Angular2'
}
}
但我被困在两个地方:
No Provider for AuthService
有任何关于这是正确的做法还是出错的建议都非常感谢。
答案 0 :(得分:3)
您需要传递父注入器,如
export class MyIfDirective {
constructor(private injector:Injector, private _viewContainer: ViewContainerRef,
private _template: TemplateRef<Object>)
{ }
@Input() set myIf(rule: string) {
let resolvedProviders = ReflectiveInjector.resolve([AdminOnly]);
let childInjector = ReflectiveInjector.fromResolvedProviders(resolvedProviders, this.injector);
let adminOnly : IRule = childInjector.get(AdminOnly);
let show = adminOnly.shouldShowElement();
show ? this.showItem() : this.hideItem();
}
private showItem() {
this._viewContainer.createEmbeddedView(this._template);
}
private hideItem() {
this._viewContainer.clear();
}
}
另见Inject service with ReflectiveInjector without specifying all classes in the dependency tree
答案 1 :(得分:0)
仅针对Angular 10+版本进行了更新:
@Injectable({
providedIn: 'any'
})
export class AdminOnly { ... }
import { Injector } from '@angular/core';
...
const injector: Injector = Injector.create({
providers: [{provide: AdminOnly, deps: []}]
});
const adminOnly: AdminOnly = injector.get(AdminOnly);
let show = adminOnly.shouldShowElement();
...