问题描述
我想根据用户的角色显示/隐藏元素(例如,某些按钮仅对管理员可见)。这可以通过* ngIf来实现,我相信,更好的方法是使用伪指令:
import { Directive,Input,TemplateRef,ViewContainerRef } from '@angular/core';
import { AuthService } from '../services/auth.service';
@Directive({
selector: '[appHasRole]',})
export class HasRoleDirective {
constructor(private auth: AuthService,private templateRef: TemplateRef<any>,private viewContainer: ViewContainerRef) {}
@input() set appHasRole(role: string) {
if (this.checkRole(role)) {
this.viewContainer.createEmbeddedView(this.templateRef);
} else {
this.viewContainer.clear();
}
}
checkRole(role: string): boolean {
return this.auth.getRole() === role;
}
}
用法:
<div *appHasRole="'admin'">
这按预期工作。不过,我很难为该组件编写单元测试。尽管阅读了Angular官方文档中的testing examples和一些相关的文章(Angular 2 / 4 - How to test Directive @Input values?和How to test the set method of @Input in an Angular directives),但我无法使其正常工作。
我很努力,因为我没有使用像这样的单独输入
<div *appHasRole [role]="'admin'">
但使用@input alias。
尝试1:
@Component({
template: `<div *appHasRole="'admin'" class="test"></div>`,})
class TestComponent {
@ViewChild(HasRoleDirective) directive: HasRoleDirective;
}
beforeEach(async(() => {
fixture = Testbed.configureTestingModule({
declarations: [HasRoleDirective,TestComponent],providers: [AuthService,HasRoleDirective,ViewContainerRef],}).createComponent(TestComponent);
testDirective = new HasRoleDirective(new AuthService(),new TemplateRef(),new ViewContainerRef());
}))
我什至没有在这里添加任何单元测试,因为ViewContainerRef is an abstract class and cannot be directly instantiated。所以我看不到任何测试方式
this.viewContainer.createEmbeddedView(this.templateRef);
采用这种方法。
尝试2:
@Component({
template: `<div *appHasRole="'admin'"></div>`,})
class TestComponent {
@ViewChild(HasRoleDirective) directive: HasRoleDirective;
}
let directive: DebugElement;
let testComponent: TestComponent;
beforeEach(() => {
fixture = Testbed.configureTestingModule({
declarations: [HasRoleDirective,imports: [HttpClientModule,RouterTestingModule],providers: [HasRoleDirective,}).createComponent(TestComponent);
fixture.detectChanges();
testComponent = fixture.componentInstance;
directive = fixture.debugElement.query(By.directive(HasRoleDirective));
console.log(directive);
});
伪指令始终为null,以防止进一步测试。甚至当我尝试使用帮助器类访问它时:
尝试3:
@Component({
template: `<div *appHasRole="'admin'" class="test"></div>`,}).createComponent(TestComponent);
fixture.detectChanges();
testComponent = fixture.componentInstance;
directive = fixture.debugElement.query(By.css('.test'));
console.log(directive);
});
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)