Angular 使用@Input FormGroups进行OnPush更改检测
想象一下Angular 2应用程序中的以下组件层次结构Angular 使用@Input FormGroups进行OnPush更改检测,angular,angular2-forms,angular2-changedetection,ngrx-store,Angular,Angular2 Forms,Angular2 Changedetection,Ngrx Store,想象一下Angular 2应用程序中的以下组件层次结构 app.component └── node.component ├── header.component ├── body.component └── footer.component 应用程序将呈现一个节点树。在ngrx/store中有一个“根”节点来反映树的状态 app.component获取保存在ngrx/store中的AppState的“切片”,即根节点上可观察到的 export class AppCom
app.component
└── node.component
├── header.component
├── body.component
└── footer.component
应用程序将呈现一个节点树。在ngrx/store
中有一个“根”节点来反映树的状态
app.component
获取保存在ngrx/store
中的AppState
的“切片”,即根节点上可观察到的
export class AppComponent {
rootNode: Observable<Node>;
constructor(private readonly store: Store<AppState>) {
this.rootNode = this.store.select(state => state.nodes);
}
}
node.component
将节点作为Input()
接收,并使用三个组件呈现它:header.component
,body.component
,footer.component
@Component({
selector: 'app-node',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class NodeComponent {
@Input() node: Node;
constructor() {}
}
注意,node.component
视图不使用async
管道,因为它不是呈现一个可观察的,而是一个普通的节点对象:
<node-header [node]="node"></node-header>
<node-body [node]="node"></node-body>
<node-footer [node]="node"></node-footer>
由于header.component
、body.component
和footer.component
都做了几乎相同的事情,我只提供header.component
的概要:
@Component({
selector: 'node-header',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class HeaderComponent implements OnInit {
@Input() node: Node;
@Input() headerForm: FormGroup;
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.headerForm = this.fb.group({
title: [this.node.title]
});
}
}
@Component({
selector: 'node-header',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class HeaderComponent implements OnInit {
@Input() node: Node;
@Input() headerForm: FormGroup;
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.headerForm = this.fb.group({
// Binds to property of node.
// {{node.title}} won't update even thought it's "local".
title: [this.node.title]
});
}
}
FormBuilder
创建一个FormGroup
,并绑定到从@Input()
接收的节点的title
属性。
将呈现表单控件以进行编辑,以及值:
<div [formGroup]="headerForm">
<input formControlName="title"name="title">
</div>
<p>Title {{ node.title }}</p>
我不记得在哪里读到过它,但我认为如果组件更新了它(自己的)数据绑定属性,就不需要进行更改检测。但是,在本例中,header.component
绑定到节点的属性,因此,{{node.title}}
视图不会更新。为了更清楚,我在标题中添加了一些注释
@Component({
selector: 'node-header',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class HeaderComponent implements OnInit {
@Input() node: Node;
@Input() headerForm: FormGroup;
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.headerForm = this.fb.group({
title: [this.node.title]
});
}
}
@Component({
selector: 'node-header',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class HeaderComponent implements OnInit {
@Input() node: Node;
@Input() headerForm: FormGroup;
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.headerForm = this.fb.group({
// Binds to property of node.
// {{node.title}} won't update even thought it's "local".
title: [this.node.title]
});
}
}
我可以在这里做些什么来确保在用户进行编辑时立即更新视图,并且只有在以后,当您在输入中键入您实际上正在从表单组更改表单控件“title”中的值时,才将更改推送到ngrx/store
?。绑定到node.title显示的是来自state的对象,因此我认为它可以按预期工作。如果将模板绑定到headerForm的值,它应该在键入时更新。类似于{{headerForm.controls.title.value}
@Component({
selector: 'node-header',
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class HeaderComponent implements OnInit {
@Input() node: Node;
@Input() headerForm: FormGroup;
constructor(private fb: FormBuilder) {}
ngOnInit() {
this.headerForm = this.fb.group({
// Binds to property of node.
// {{node.title}} won't update even thought it's "local".
title: [this.node.title]
});
}
}