我正在尝试通过将几个验证输入压缩到指令中来简化模板过程,我可以将它们放置在需要它们的<input>
元素上。
有问题的输入看起来像这样:
<input [(ngModel)]='options.org_name' required id="org_name" type="text" nbInput fullWidth
placeholder="What is your organization called?"
[appValidating]='this'
minlength="3" maxlength="40" />
我的指令是[appValidating]
。 appValidating的代码是这样的:
@Directive({
selector: '[appValidating]'
})
export class ValidatingDirective {
@Input('appValidating') validator: IValidatingComponent;
@Input() id: string;
@HostBinding('status')
get status() {
return this.validator.validity[this.id] === true ? null : 'danger';
}
@HostListener('input', ['$event'])
onInput(event: any) {
this.validator.checkValidity(this.id, event);
}
constructor() { }
}
我的问题是,它不允许我在'status'上使用@HostBinding,这是nbInput指令的输入,该指令也位于元素上。
Uncaught (in promise): Error: Template parse errors:
Can't bind to 'status' since it isn't a known property of 'input'.
我是否可以从我的指令中绑定该指令的输入?
答案 0 :(得分:1)
首先,您可以使用HostBinding设置属性,但最终无法满足您的需求
@HostBinding('attr.status') // this will set an attribute on the element
这对您不起作用的原因是,它不是您要设置的角度感知属性,因此它无法绑定到nbInput指令的@Input。
我考虑了一下,尝试了解决该问题的几种方法,最后解决了这个问题,但是要使它正常工作,您可能需要具有访问权限并能够更改这两个指令。
@Directive({
selector: '[firstDirective]',
})
export class FirstDirective {
@Input('status') private status: boolean;
@HostListener('click', ['$event'])
public onHostClicked(event: MouseEvent): void {
event.preventDefault();
event.stopImmediatePropagation();
event.stopPropagation();
console.log('first directive: ', this.status);
}
}
第一个指令的状态为Input,主机元素的onClick会注销状态
@Directive({
selector: '[secondDirective]',
})
export class SecondDirective {
@Input('status') private status = false;
@Output('statusChange') private statusChangeEvent = new EventEmitter(
this.status,
); // an output event named as attributeNameChange is how you tell a two way bound attribute that it's value has changed
@HostListener('click', ['$event'])
public onHostClicked(event: MouseEvent): void {
event.preventDefault();
event.stopImmediatePropagation();
event.stopPropagation();
this.status = !this.status; // toggle the boolean
this.statusChangeEvent.emit(this.status); // emit that it changed
}
第二个指令接受状态输入并发出statusChange输出,并且宿主元素的onClick翻转状态值并发出其已更改。
@Component({
template: '<button firstDirective secondDirective [(status)]="status">Change Status</button>',
})
export class Component {
status = true; // the value in the implementing component that is being toggled
constructor() {}
}
因此,在上面的示例中,正在发生的事情是在实现组件中设置了一个值,两个指令都可以访问该值,并且该值充当两个指令之间的传递。每当第二条指令单击时,它就会翻转状态布尔值,而第一条指令会看到更改。