如何在子组件观察到输入变化时调用父组件的功能?
以下是HTML结构.
# app.comopnent.html
<form>
<textbox>
<input type="text">
</textbox>
</form>
# textbox.component.html
<div class="textbox-wrapper">
<ng-content>
</div>
Run Code Online (Sandbox Code Playgroud)
限制如下.
ng-content并且需要将input元素投影到它.input元素输入时,在TextboxComponent中发出一个事件.input元素具有更多属性,例如<input type="text" (input)="event()">.我正在编写代码,但无法找到解决方案......
# input.directive.ts
@Directive({ selector: 'input', ... })
export class InputDirective {
ngOnChanges(): void {
// ngOnChanges() can observe only properties defined from @Input Decorator...
}
}
# textbox.component.ts
@Component({ selector: 'textbox', ... })
export class TextboxComponent {
@ContentChildren(InputDirective) inputs: QueryList<InputDirective>;
ngAfterContentInit(): void {
this.inputs.changes.subscribe((): void => {
// QueryList has a changes property, it can observe changes when the component add/remove.
// But cannot observe input changes...
});
}
}
Run Code Online (Sandbox Code Playgroud)
该input事件正在冒泡,可以在父组件上进行侦听
<div class="textbox-wrapper" (input)="inputChanged($event)">
<ng-content></ng-content>
</div>
Run Code Online (Sandbox Code Playgroud)
在ngAfterViewInit(),找到感兴趣的元素,然后命令性地添加事件监听器.下面的代码只假设一个输入:
@Component({
selector: 'textbox',
template: `<h3>textbox value: {{inputValue}}</h3>
<div class="textbox-wrapper">
<ng-content></ng-content>
</div>`,
})
export class TextboxComp {
inputValue:string;
removeListenerFunc: Function;
constructor(private _elRef:ElementRef, private _renderer:Renderer) {}
ngAfterContentInit() {
let inputElement = this._elRef.nativeElement.querySelector('input');
this.removeListenerFunc = this._renderer.listen(
inputElement, 'input',
event => this.inputValue = event.target.value)
}
ngOnDestroy() {
this.removeListenerFunc();
}
}
Run Code Online (Sandbox Code Playgroud)
与Günter的声明式方法相比,这个答案本质上是一种必要的方法.如果您有多个输入,这种方法可能更容易扩展.
似乎没有办法使用@ContentChild()(或@ContentChildren())在用户提供的模板中找到DOM元素(即ng-content内容)... @ContentChild(input)似乎不存在的东西.因此我使用的原因querySelector().
在这篇博文中,http://angularjs.blogspot.co.at/2016/04/5-rookie-mistakes-to-avoid-with-angular.html,Kar建议用input选择器定义一个指令(比如InputItem)然后使用@ContentChildren(InputItem) inputs: QueryList<InputItem>;.然后我们不需要使用querySelector().但是,我并不特别喜欢这种方法,因为TextboxComponent的用户必须知道在directives数组中也包含InputItem (我想一些组件文档可以解决问题,但我仍然不是粉丝).这是这种方法的掠夺者.
| 归档时间: |
|
| 查看次数: |
14916 次 |
| 最近记录: |