本文介绍了@Output 与 EventEmitter 从子级到父级,视图不会在父级中更新的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当在 map.component.ts 中单击标记时,它会将数据发送到 home.component.ts.这是由这一行检测到的 </x-map>

When a marker is clicked in map.component.ts, it emits the data to home.component.ts. This is detected by this line <x-map (change)="updateSelected($event)"></x-map>

因此,当 updateSelected 运行时,它会将 opened 更新为 true.

So when updateSelected is run it updates opened to true.

当检查控制台日志时,它返回 true 但工具栏中的 {{ opens }}sidenav 仍然有 openedfalse.

When checking the console log it returns with true but the {{ opened }} in the toolbar and the sidenav still have opened as false.

当我稍微调整窗口大小时,home.component.ts 的视图会更新,并且工具栏中的 {{ opens }} 显示 trueSidenav 打开.

When I resize the window slightly the view of home.component.ts updates and {{ opened }} in the toolbar shows true and the sidenav opens.

我该如何克服这个问题?

How can I overcome this issue?

home.component.html

<mat-toolbar color="primary" class="mat-elevation-z6">
  <mat-toolbar-row>
    <span fxLayoutAlign="start center">
      <button mat-icon-button (click)="toggleSidenav()">
        <mat-icon aria-label="Example icon-button with a heart icon">menu</mat-icon>
      </button>
      {{ opened }}
    </span>
  </mat-toolbar-row>
</mat-toolbar>

<mat-sidenav-container fullscreen class="sidenav-container">
  <mat-sidenav #sidenav mode="side" [opened]="opened" class="mat-elevation-z6">
    Sidenav content
  </mat-sidenav>
  <mat-sidenav-content>
    <x-map (change)="updateSelected($event)"></x-map>
  </mat-sidenav-content>
</mat-sidenav-container>

home.component.ts

import { Component, Input, OnInit, SimpleChanges } from '@angular/core';

    @Component({
      selector: 'x-home',
      templateUrl: './home.component.html',
      styleUrls: ['./home.component.scss']
    })
    export class HomeComponent implements OnInit {

      constructor() { }
      opened = false;

      updateSelected($event) {
        console.log($event);
        this.opened = true;
        console.log(this.opened);
      }
    }

ma​​p.component.ts

import { Component, EventEmitter, Input, OnChanges, OnInit, Output } from '@angular/core';
import { ApiService } from '../api.service';
import { } from '@types/googlemaps';

@Component({
  selector: 'x-map',
  templateUrl: './map.component.html',
  styleUrls: ['./map.component.scss']
})
export class MapComponent implements OnChanges, OnInit {
  constructor(private apiService: ApiService) { }
  map: any;
  markersArray: any[] = [];
  devices: any;
  @Output() change: EventEmitter<any> = new EventEmitter();

  markerClick(marker) {
    google.maps.event.addListener(marker, 'click', () => {
      this.change.emit(this.devices.find(d => d.ChargeDeviceId === marker.title));
    });
  }

  plot() {
    for (let i = 0; i < this.devices.length; i++) {
      const marker = new google.maps.Marker({
        map: this.map,
        position: new google.maps.LatLng(this.devices[i].ChargeDeviceLocation.Latitude, this.devices[i].ChargeDeviceLocation.Longitude),
        title: this.devices[i].ChargeDeviceId,
      });
      this.markerClick(marker);
      this.markersArray.push(marker);
    }
  }

  ngOnChanges() {
    console.log(this.resize);
    if (this.resize) {
      this.onResize();
    }
  }

  ngOnInit() {
    this.apiService.get().subscribe(
      (res) => {
        this.devices = res['ChargeDevice'];
        this.plot();
      },
      (err) => {
        console.log(err);
      }
    );

    this.map = new google.maps.Map(document.getElementById('map'), {
      center: {lat: 54.797753, lng: -2.871329},
      zoom: 8
    });
  }
}

推荐答案

属性未更新的原因是未按预期触发更改检测.未运行更改检测的原因是您的谷歌地图方法的回调在角度区域之外运行.

The reason for your property not being updated is that change detection is not triggered as you expect it to. And the reason that change detection is not run is because the callback for your google maps method is run outside of the angular zone.

要强制该代码在角度区域内运行,您可以像这样用 NgZone 包裹它:

To force that code to be run within the angular zone, you can wrap it with NgZone like this:

import { ..., ..., NgZone } from '@angular/core';  // <= IMPORT

//...

export class MapComponent implements OnChanges, OnInit {
    constructor(private zone: NgZone, ...) { }   // <= INJECT

    // ....

    markerClick(marker) {
        google.maps.event.addListener(marker, 'click', () => {
            this.zone.run(() => {   // <= USE
                this.change.emit(this.devices.find(d => d.ChargeDeviceId === marker.title));
            });
        });
    }
}

这篇关于@Output 与 EventEmitter 从子级到父级,视图不会在父级中更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-16 07:39