使用双向数据绑定时,似乎无法观察父组件中的更改。
我有一个用于收集标签列表的自定义输入组件。已建立双向数据绑定,并在此组件与其父组件之间进行工作。
// the parent component is just a form
// here is how I'm adding the child component
<input-tags formControlName="skillField" [(tags)]='skillTags' (ngModelChange)="skillTagUpdate($event)"></input-tags>
在父组件中,您如何查看绑定变量的更改?尽管它始终是最新的(我已经确认了这一点),但我找不到任何对更改做出反应的指导。
我尝试过:
ngOnChanges(changes: SimpleChanges) {
if (changes['skillTags']) {
console.log(this.skillTags); // nothing
}
}
和
skillTagUpdate(event){
console.log(event); // nothing
}
更新:StackBlitz
答案 0 :(得分:3)
实现自己的双向绑定时,必须实现事件发射器。语法是强制性的。
这意味着如果值更改,您将有一个钩子可以收听。
这是一个演示:
<hello [(name)]="name" (nameChange)="doSomething()"></hello>
_name: string;
@Output() nameChange = new EventEmitter();
set name(val) {
this._name = val;
this.nameChange.emit(this._name);
}
@Input()
get name() {
return this._name;
}
counter = 0;
ngOnInit() {
setInterval(() => {
this.name = this.name + ', ' + this.counter++;
}, 1000);
}
据我所知,这似乎是使用它的较不烦人的方式,无论哪种方式,任何两种绑定方式都将遵循相同的规则,即以Change
单词结尾!
答案 1 :(得分:0)
您可以收听更改:
<input-tags formControlName="skillField" [tags]='skillTags' (tagsChange)='skillTags=$event; skillTagUpdate();'></input-tags>
或使用getter和setter:
get skillTags(): string {
return ...
}
set skillTags(value) {
variable = value;
}
另一种方法:
export class Test implements DoCheck {
differ: KeyValueDiffer<string, any>;
public skillTags: string[] = [];
ngDoCheck() {
const change = this.differ.diff(this.skillTags);
if (change) {
change.forEachChangedItem(item => {
doSomething();
});
}
}
constructor(private differs: KeyValueDiffers) {
this.differ = this.differs.find({}).create();
}
}}
答案 2 :(得分:0)
1。您可以使用output(eventemitter)
2。最简单的解决方案是rxjs / subject。它可以同时是观察者和可观察的
用法:
1。在服务中创建主题属性:
import { Subject } from 'rxjs';
export class AuthService {
loginAccures: Subject<boolean> = new Subject<boolean>();
}
2。当事件在子页面/组件使用中发生时:
logout(){
this.authService.loginAccures.next(false);
}
3。并在父页面/组件中订阅主题:
constructor(private authService: AuthService) {
this.authService.loginAccures.subscribe((isLoggedIn: boolean) => {this.isLoggedIn = isLoggedIn;})
}
更新
对于双向绑定,您可以使用viewchild来访问子组件的项目和属性
<input-tags #test></<input-tags>
和ts文件中
@ViewChild('test') inputTagsComponent : InputTagsComponent;
save()
{
var childModel = this.inputTagsComponent.Model;
}
答案 3 :(得分:0)
不知道这是您要找的内容,但是您是否尝试过使用@Input()?
在子组件中
@Input() set variableName(value: valueType) {
console.log(value);
}
在父组件中
<input-tags formControlName="skillField" [(tags)]='skillTags'
[valiableName]="skillTagUpdate($event)"></input-tags>
每次更改绑定到该函数的对象时,都会调用输入函数。
答案 4 :(得分:0)
您的实现实际上不是双向数据绑定,父组件和子组件只是共享对同一skillTags
变量的引用。
语法[(tags)]='skillTags'
是[tags]='skillTags' (tagsChange)='skillTags = $event'
的语法糖
您需要在子组件中实现tagsChange
,如下所示:@Output('tagsChange') tagsChange = new EventEmitter<any>();
,然后任何时候要将tags
修改为子组件,都不要直接执行,而是使用{ {1}}。
这时,您将具有真正的双向数据绑定,并且父组件是变量的唯一所有者(负责对变量应用更改并将更改传播给子代)。
现在,在父组件中,如果您想做的事情不只是this.tagsChange.emit(newValue)
(暗中用skillTags = $event
完成),那么只需用[(tags)]='skillTags'
添加另一个侦听器即可。