父级的角度子组件事件多次触发

时间:2020-06-15 19:24:17

标签: javascript angular typescript

我在我的父母身上有一个点击事件(updateExpanded),当我点击时,我将触发并向孩子发送事件。然后,孩子订阅该事件。问题在于该事件被调用了4次。我已经尝试了所有可能找到的东西,但似乎无法看到为什么它应该只被触发一次时才会被频繁触发。

当父组件扩展时,我需要在子组件中加载数据。

父母TS

@Output()
isExpandedEvent = new EventEmitter<string>();

 updateExpanded(id: string) {
        this.isExpandedEvent.emit(id);
        console.log(id + " parent opened");
    }

ngOnDestroy() {
        if (this.isExpandedEvent) {
            this.isExpandedEvent.unsubscribe();
        }
    }

父HTML

<ngx-planned-maintenance-detail [model]="plannedMaintenanceRecurring" [index]="i" [expandedEventEmitter]="isExpandedEvent">
                </ngx-planned-maintenance-detail>

.........

儿童TS

 @Input()
  expandedEventEmitter = new EventEmitter<string>();

  ngOnInit() {
    this.expandedEventEmitter.subscribe(data => {
        if (data) {
             console.log("detail complete");
        }
     });
  }

ngOnDestroy() {
    this.expandedEventEmitter.unsubscribe();
  }

父级被调用一次,详细信息被调用了4次,如下所示 enter image description here

2 个答案:

答案 0 :(得分:2)

那是因为您要将可观察对象(ArrayList<Drawer> drawerList = new ArrayList<>(); drawerList.add(new Drawer(, "My Mall")); )绑定到属性。这里有两个问题。

  1. EventEmitter不是将信息 从父 传达给的正确方法孩子。反之亦然。
  2. 如果您不控制更改检测策略,则绑定到属性的可观察对象/函数可能会被触发比预期多的次数。

如果您查看EventEmitter源,它是RxJS Subject的简单接口扩展。因此,在这种情况下,您可以做的是创建一个singleton service,它将使用RxJS EventEmitter直接保存组件之间的共享信息。

shared.service.ts

Subject

现在您可以在两个组件中注入此单例并使用共享数据。

parent.component.ts

import { Subject } from 'rxjs';

@Injectable({providedIn: 'root'})
export class SharedService {
  isExpanded = new Subject<any>();

  constructor() { }

  pushIsExpanded(value: any) {
    this.isExpanded.next(value);
  }

  getIsExpanded() {
    return this.isExpanded.asObservable();
  }
}

child.component.ts

export class ParentComponent {
  constructor(private sharedService: SharedService) { }

  updateExpanded(id: string) {
    this.sharedService.pushIsExpanded(id);
  }
}

答案 1 :(得分:0)

使用ViewChild向孩子发送点击事件。

使用EventEmitter将点击事件从子级发送到父级。