我正在尝试使用一个支持双向绑定的属性来实现一个指令:[(appfocused)]="isFocused"
。组件可以将其isFocused
属性设置为true以关注元素,但是一旦元素失去焦点,变量将恢复为false。
我已阅读(here和here),实现此类绑定的关键是@Input
和@Output
的两个属性命名相同但是输出一个后缀为Change
。所以这是我到目前为止的实现(在TypeScript中):
@Directive({
selector: '[appfocused]'
})
export class FocusedDirective implements OnChanges, AfterViewInit {
@Input('appfocused')
focused: boolean;
@Output('appfocused')
focusedChange: EventEmitter<boolean> = new EventEmitter();
constructor(private elementRef: ElementRef, private renderer: Renderer) { }
ngAfterViewInit() {
this.renderer.listen(this.elementRef.nativeElement, 'blur', () => {
this.setFocused(false);
});
}
ngOnChanges() {
if (this.focused) {
setTimeout(() => {
this.elementRef.nativeElement.focus();
}, 0);
}
}
private setFocused(value: boolean) {
this.focused = value;
this.focusedChange.emit(this.focused);
console.log('focused set to ' + value);
}
}
输入属性工作正常,但我无法使输出属性起作用。感谢console.log
调用,我知道正在点击focusedChange.emit()
行,但它对属性绑定的值没有影响。
Here is a working example (plunker).它包含一个虚拟组件,用于显示和设置isFocused
属性的值:
@Component({
selector: 'my-app',
template: `
<div>
<textarea [(appfocused)]="isFocused"></textarea>
</div>
<a (click)="focus()" href="#">Focus</a>
{{isFocused}}
`,
})
export class App {
isFocused = false;
focus() {
this.isFocused = true;
}
}
按下焦点链接将按预期聚焦textarea
。但是,单击它不会重置isFocused
变量。再次按下链接无效 - isFocused
的值已经为真,因此Angular无法检测到任何更改。
我错过了什么?
答案 0 :(得分:3)
正如您提到的文章所述,要使用双向绑定速记语法,输出的名称必须与输入加上“更改”后缀<相同/强>
所以你几乎就在那里 - 你必须正确命名@Output()
:不是“ appfocused ”,而是“ appfocused 更改 < / em>“而不是:
@Output('appfocusedChange')
focusedChange: EventEmitter<boolean> = new EventEmitter();