[英]@Output with EventEmitter from child to parent, view doesn't update in parent
When a marker is clicked in map.component.ts, it emits the data to home.component.ts. 在map.component.ts中单击标记时,它将数据发送到home.component.ts。 This is detected by this line
<x-map (change)="updateSelected($event)"></x-map>
此行
<x-map (change)="updateSelected($event)"></x-map>
So when updateSelected
is run it updates opened
to true
. 因此,当运行
updateSelected
时,它将更新opened
为true
。
When checking the console log it returns with true
but the {{ opened }}
in the toolbar and the sidenav
still have opened
as false
. 当检查控制台日志时,它返回
true
但是工具栏中的{{ opened }}
和sidenav
仍为false
opened
。
When I resize the window slightly the view of home.component.ts
updates and {{ opened }}
in the toolbar shows true
and the sidenav opens. 当我稍微调整窗口大小时,
home.component.ts
的视图将更新,并且工具栏中的{{ opened }}
显示为true
,并且sidenav打开。
How can I overcome this issue? 我该如何克服这个问题?
home.component.html 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 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 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
});
}
}
I was able to fix this by importing ApplicationRef
and then adding this.app.tick();
我能够通过导入
ApplicationRef
然后添加this.app.tick();
来解决此问题this.app.tick();
to the end of my updateSelected()
function. 到我的
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() {
}
}
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 .
而未运行更改检测的原因是,您的google maps方法的回调是在角度区域之外运行的 。
To force that code to be run within the angular zone, you can wrap it with NgZone
like this: 要强制该代码在角度区域内运行,可以使用
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.