0

我们在 Angular 2 中实现了一个结构指令,只为具有特定角色的用户显示内容。在生产系统中,一切正常。

@Directive({ selector: '[pdHasRole]' })
export class UserHasRoleDirective {

    constructor(private templateRef: TemplateRef<any>,
        private viewContainer: ViewContainerRef,
        private userService: UserService) {
    }

    @Input() set pdHasRole(role: string) {

        this.viewContainer.clear();
        if (this.userService.userContext && this.userService.userContext.roles && this.userService.userContext.roles.length > 0) {
            if (role) {
                if (this.userService.userContext.roles.indexOf(role) > -1) {
                    this.viewContainer.createEmbeddedView(this.templateRef);
                }
            }
        }
    }
}

当我们使用 TestBed 实施一些测试时,问题就出现了。如果我们使用只包含字母和数字的角色作为输入(例如 APP1role1),一切正常。如果我们使用带有冒号等的角色。(例如 APP1:role1)我们得到一个错误:

模板解析错误:TypeError:无法读取未定义的属性“toUpperCase”

这是用于测试结构指令的规范组件:

describe('hasRole', () => {
    beforeEach(() => {
        TestBed.configureTestingModule({
            declarations: [TestHasRoleComponent],
            providers: [{ provide: UserService, useClass: FakeUserServiceWithRoles }],
            imports: [CommonModule, SharedModule]
        });
    });

    it('desired role; div should be included in DOM', () => {
        const role = 'APP1:role1';
        const template = `<div *pdHasRole="` + role + `">Test with role: ` + role + `</div>`;
        const fixture = createTestComponent(template)
        fixture.detectChanges();
        expect(fixture.debugElement.queryAll(By.css('div')).length).toEqual(1);
    });
});

@Component({ selector: 'pd-test-cmp', template: '' })
class TestHasRoleComponent {
}

function createTestComponent(template: string): ComponentFixture<TestHasRoleComponent> {
    return TestBed.overrideComponent(TestHasRoleComponent, { set: { template: template } })
        .createComponent(TestHasRoleComponent);
}

我很确定角色输入中的“:”会导致问题。

有人知道为什么吗?帮助会很棒!

提前致谢

4

1 回答 1

0

*将评估以星号为前缀的结构指令。您正在传递一个字符串。

因此,将其替换为以下内容:

*pdHasRole="'` + role + `'"

此外,您正在使用字符串插值字符串,但随后求助于正常连接。你也可以写:

const template = `<div *pdHasRole="'${role}'">Test with role: ${role}</div>`;
于 2018-08-14T16:09:23.240 回答