如何使用@input别名

问题描述

我想根据用户的角色显示/隐藏元素(例如,某些按钮仅对管理员可见)。这可以通过* 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 (将#修改为@)