繁体   English   中英

@Output与EventEmitter从子级到父级,父级中的视图未更新

[英]@Output with EventEmitter from child to parent, view doesn't update in parent

在map.component.ts中单击标记时,它将数据发送到home.component.ts。 此行<x-map (change)="updateSelected($event)"></x-map>

因此,当运行updateSelected时,它将更新openedtrue

当检查控制台日志时,它返回true但是工具栏中的{{ opened }}sidenav仍为false opened

当我稍微调整窗口大小时, home.component.ts的视图将更新,并且工具栏中的{{ opened }}显示为true ,并且sidenav打开。

我该如何克服这个问题?

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);
      }   
    }

map.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
    });
  }
}

我能够通过导入ApplicationRef然后添加this.app.tick();来解决此问题this.app.tick(); 到我的updateSelected()函数的末尾。

import { ApplicationRef, 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(private app: ApplicationRef) { }
  opened = false;

  toggleSidenav() {
    this.opened = !this.opened;
  }

  setSidenav(val: boolean) {
    this.opened = val;
  }

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

  ngOnInit() {
  }
}

您的媒体资源未更新的原因是未按预期触发更改检测。 而未运行更改检测的原因是,您的google maps方法的回调是在角度区域之外运行的

要强制该代码在角度区域内运行,可以使用NgZone将其包装,如下所示:

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));
            });    
        });
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM