@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>
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
,但工具栏中的 {{已打开}}
和 sidenav
仍具有打开
为 false
.
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
的视图会更新,并且工具栏中的 {{已打开}}
显示 true
并打开sidenav.
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);
}
}
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
});
}
}
推荐答案
未更新您的媒体资源的原因是未按预期触发变更检测.之所以没有运行更改检测,是因为您的google maps方法的回调是在角度区域之外运行的.
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从子级到父级,父级中的视图未更新的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!