Angular 角度7+;,调用子组件';父母的方法是什么?
有时我想从父组件调用子组件的方法,或者以某种方式通知子组件(从父组件)调用某些东西 1st(从父级调用子组件的方法):Angular 角度7+;,调用子组件';父母的方法是什么?,angular,angular7,Angular,Angular7,有时我想从父组件调用子组件的方法,或者以某种方式通知子组件(从父组件)调用某些东西 1st(从父级调用子组件的方法): // CHILD @Component({ selector: 'child-component', template: '<p>child</p>' }) class ChildComponent { doSomething() { console.log('I am from child') } } // PARENT
// CHILD
@Component({
selector: 'child-component',
template: '<p>child</p>'
})
class ChildComponent {
doSomething() {
console.log('I am from child')
}
}
// PARENT
@Component({
selector: 'parent-component',
template: '<child-component></child-component>',
})
class ParentComponent{
@ViewChild(ChildComponent ) child: ChildComponent;
ngAfterViewInit() {
this.child.doSomething();
}
}
//CHILD
export class ChildComponent implements OnInit {
@Input() notify: Subject<boolean>;
ngOnInit(){
this.notify.subscribe(v => {
console.log("I am from child");
});
}
}
//PARENT
export class ParentComp {
notify: Subject<boolean> = new Subject();
notifyChild(){
this.notify.next(true);
}
}
//子对象
@组成部分({
选择器:'子组件',
模板:“子项”
})
类子组件{
doSomething(){
console.log('我来自孩子')
}
}
//母公司
@组成部分({
选择器:“父组件”,
模板:“”,
})
类ParentComponent{
@ViewChild(ChildComponent)子级:ChildComponent;
ngAfterViewInit(){
这个。孩子。doSomething();
}
}
2nd(通知子组件调用某物):
// CHILD
@Component({
selector: 'child-component',
template: '<p>child</p>'
})
class ChildComponent {
doSomething() {
console.log('I am from child')
}
}
// PARENT
@Component({
selector: 'parent-component',
template: '<child-component></child-component>',
})
class ParentComponent{
@ViewChild(ChildComponent ) child: ChildComponent;
ngAfterViewInit() {
this.child.doSomething();
}
}
//CHILD
export class ChildComponent implements OnInit {
@Input() notify: Subject<boolean>;
ngOnInit(){
this.notify.subscribe(v => {
console.log("I am from child");
});
}
}
//PARENT
export class ParentComp {
notify: Subject<boolean> = new Subject();
notifyChild(){
this.notify.next(true);
}
}
//子对象
导出类ChildComponent实现OnInit{
@输入()通知:主题;
恩戈尼尼特(){
this.notify.subscribe(v=>{
console.log(“我来自儿童”);
});
}
}
//母公司
导出类ParentComp{
通知:主题=新主题();
notifyChild(){
this.notify.next(true);
}
}
我的问题是:
1) 第一种方法的利弊是什么?另外,如果您从父级调用子级的方法,这是否意味着您的组件的体系结构不好,或者需要修复其他问题
2) 第二种方法的利弊是什么
3) 避开它们好吗
我正在拼命地寻找这些问题的答案(有解释),如果有人能提供答案那就太好了。如果可能的话,我会避免使用任何一种方法。如果你发现自己需要做很多这件事,那么你可能没有在父母和孩子之间正确地划分责任。您应该将所有必要的数据传递给子级,以便它知道何时调用任何函数,如果仍然不调用,则可能不是组件的责任。话虽如此,如果你发现自己正在编写一个相当复杂的应用程序,并且仍然需要大量的这个功能,我会使用类似ngrx的东西来正确管理状态。此外,如果要使用第二种方法,则应将主题分离为服务。至于推理,随着应用程序规模和复杂性的增长,依赖可预测的信息流和操作非常方便,这就是为什么ngrx可能有用,但在应用程序中多次使用第一种或第二种方法可能不会杀死你。你可以使用changedetection:
// CHILD
@Component({
selector: 'child-component',
template: '<p>child</p>',
changeDetection: ChangeDetectionStrategy.OnPush
})
class ChildComponent implements onChanges{
@Input() status: boolean;
doSomething() {
console.log('I am from child')
}
ngOnChanges(changes: SimpleChanges) {
if (changes.status) {
this.doSomething();
}
}
}
// PARENT
@Component({
selector: 'parent-component',
template: '<child-component [status]="status"></child-component>',
})
class ParentComponent{
status: boolean;
ngAfterViewInit() {
this.status = true;
}
}
//子对象
@组成部分({
选择器:'子组件',
模板:“child”,
changeDetection:ChangeDetectionStrategy.OnPush
})
类ChildComponent实现onChanges{
@输入()状态:布尔;
doSomething(){
console.log('我来自孩子')
}
ngOnChanges(更改:SimpleChanges){
如果(更改状态){
这个。doSomething();
}
}
}
//母公司
@组成部分({
选择器:“父组件”,
模板:“”,
})
类ParentComponent{
状态:布尔型;
ngAfterViewInit(){
this.status=true;
}
}
这两种实现都违背了关注点分离的原则。子组件不应该负责为父组件计算内容,因为这意味着没有子组件,父组件可能无法工作。
如果不同的组件需要一个函数或一些计算值,则可能应该将它们放在一个公共服务中,以便注入到两个组件中。答案在很大程度上取决于您想要实现什么。在我的公司里,我们一般都尽量避开主题,但也尽量避开儿童。如果我们需要在它们之间进行选择,ViewChild将是我们的首选。无法真正解释,但主题更复杂,更难理解。我不认为1方法有任何问题,因为您正在调用child的方法。它类似于使用html按钮并调用它的click事件。我认为组件是用户添加的自定义标记,所以如果您在ts文件和调用方法中使用它们,就不会有什么问题。注意:这是我的观点,当存在父子关系时,我不会特别使用第二种方法,相反,我应该创建带有主题的服务并注入该服务以提供组件之间的通信,您可以参考angular.io站点,其中使用服务是提供组件之间通信的一种方式