我正在使用Ionic 3,而我正在使用Google Maps插件。我有两个页面,一个列表和一个地图。我在两个视图上显示相同的对象,当您单击列表条目或标记(信息窗口)时,将打开对象的详细信息页面,您可以对所选对象进行评级。
无论如何,当我通过列表打开详细页面时,一切正常,但是当我通过map-marker打开详细页面时,双向数据绑定停止工作。在下面的代码中,您可以在评级对话框中找到<rating-input>
组件。这是代码无效。
我尝试使用简单的输入文本来确定它是否真的是双向数据绑定,或者它是否是我的组件。使用简单的文本框,数据绑定无效。
以下是代码:
//adding the markers to the map and adding the clicklisteners
putMarkersForMarkets(markets: Christmasmarket[]) {
markets.forEach(market => {
let isOpen = this.openinghoursService.isOpenAt(market, new Date());
this.map.addMarker({
title: market.name,
icon: isOpen ? 'green' : 'red',
animation: 'DROP',
position: {
lat: market.position.latitude,
lng: market.position.longitude
}
}).then(marker => {
marker.on(GoogleMapsEvent.INFO_CLICK)
.subscribe(() => {
this.onClickMarket(market);
});
});;
});
}
onClickMarket(market: Christmasmarket) {
this.map.setVisible(false);
this.map.setClickable(false);
this.app.getRootNav().push(MarketDetailPage, { data: market });
}
评级-Popup html:
<ion-header>
<ion-navbar color="primary">
<ion-title>{{'RATINGDIALOG.TITLE' | translate}}</ion-title>
<ion-buttons end>
<button ion-button icon-only (click)="dismiss()">
<ion-icon name="close"></ion-icon>
</button>
</ion-buttons>
</ion-navbar>
</ion-header>
<ion-content padding>
<form #form="ngForm">
<b>{{'RATINGDIALOG.HEADERMARKET' | translate}}</b><br>
<rating-input [(rating)]="rating" [texts]="ratingTexts" name="rating"></rating-input>
<b>{{'RATINGDIALOG.HEADERPRICE' | translate}}</b><br>
<rating-input [(rating)]="ratingPrice" symbol="logo-euro" [texts]="ratingPriceTexts"></rating-input>
<input type="text" [(value)]="meinval">
{{meinval}}
</form>
</ion-content>
<ion-footer>
<ion-row>
<ion-col>
<button [disabled]="rating == 0 || ratingPrice == 0" ion-button full color="secondary" (click)="saveRating()">
{{'RATINGDIALOG.SAVE' | translate}}
</button>
</ion-col>
<ion-col>
<button ion-button full color="secondary" (click)="dismiss()">{{'RATINGDIALOG.CANCEL' | translate}}
</button>
</ion-col>
</ion-row>
</ion-footer>
评级弹出打字稿:
import { Component, OnInit } from '@angular/core';
import { ViewController, NavParams } from 'ionic-angular';
import { Christmasmarket } from "../../../model/christmasmarket";
import { ChristmasMarketService } from "../../../services/christmasmarketservice";
import { TranslateService } from "@ngx-translate/core";
@Component({
selector: 'rating-dialog',
templateUrl: 'ratingdialog.component.html'
})
export class RatingDialogComponent implements OnInit {
rating: number;
ratingPrice: number;
ratingTexts: Array<string>;
ratingPriceTexts: Array<string>;
market: Christmasmarket;
meinval: String;
constructor(
private viewCtrl: ViewController,
private navParams: NavParams,
private christmasMarketService: ChristmasMarketService,
private translate: TranslateService
) {
}
ngOnInit(): void {
this.translate.get('RATINGTEXTS').subscribe(res => {
this.ratingTexts = [];
this.ratingTexts.push(res['VALUE1']);
this.ratingTexts.push(res['VALUE2']);
this.ratingTexts.push(res['VALUE3']);
this.ratingTexts.push(res['VALUE4']);
this.ratingTexts.push(res['VALUE5']);
});
this.translate.get('RATINGPRICETEXTS').subscribe(res => {
this.ratingPriceTexts = [];
this.ratingPriceTexts.push(res['VALUE1']);
this.ratingPriceTexts.push(res['VALUE2']);
this.ratingPriceTexts.push(res['VALUE3']);
this.ratingPriceTexts.push(res['VALUE4']);
this.ratingPriceTexts.push(res['VALUE5']);
});
this.market = this.navParams.get('data');
this.rating = 0;
this.ratingPrice = 0;
this.christmasMarketService.findRatingOfMarket(this.market.id).then(rating => {
if (rating) {
this.rating = rating.rating;
this.ratingPrice = rating.ratingPrice;
}
}).catch(e => {
console.log(e);
});
}
dismiss() {
this.viewCtrl.dismiss(this.market);
}
saveRating() {
this.christmasMarketService.rateMarket(this.market.id, this.rating, this.ratingPrice).then(market => {
this.market = market;
this.dismiss();
console.log(market);
}).catch(e => {
console.log(e);
});
}
}
评级输入组件html
<button ion-button icon-only clear="true" (click)="onClickRating(num)" *ngFor="let num of possibleRatings">
<ion-icon [name]="symbol" [color]="rating >= num ? 'black' : 'grey'"></ion-icon>
</button>
<p *ngIf="texts">
{{texts[rating-1]}}
</p>
<p *ngIf="!rating || rating == 0">
-
</p>
评级输入组件打字稿
从&#34; @ angular / core&#34;;
导入{Component,Input,Output,EventEmitter}@Component({
selector: 'rating-input',
templateUrl: 'ratinginput.component.html'
})
export class RatingInputComponent{
@Input() @Output() rating: number;
@Input() symbol: string = 'star';
@Input() texts : Array<string>;
@Output() ratingChange = new EventEmitter();
possibleRatings: Array<number> = [1, 2, 3, 4, 5];
onClickRating(rating: number) {
this.rating = rating;
this.ratingChange.emit(this.rating);
}
}
答案 0 :(得分:1)
问题在于:
StationId
来自google maps api的点击事件使用自己的事件侦听器,您必须使用.then(marker => {
marker.on(GoogleMapsEvent.INFO_CLICK)
.subscribe(() => {
this.onClickMarket(market);
});
});
收听它们。问题是,这是在addListener
之外运行的。要重新进入该区域,在发生此类事件后,您需要将ngZone
注入您的组件,然后执行ngZone
:
ngZone.run()
这将确保在constructor(private readonly ngZone: NgZone) {}
// ...
putMarkersForMarkets(): void {
// ...
.then(marker => {
marker.on(GoogleMapsEvent.INFO_CLICK).subscribe(() => {
this.ngZone.run(() => this.onClickMarket(market));
});
});
}
方法内运行的任何代码都将在区域内运行,因此将触发更改检测
答案 1 :(得分:-1)
您可以使用Ng区域
import { NgZone } from '@angular/core';
export class AppComponent {
constructor(public zone: NgZone){
window['AppComponent'] = {component: this, zone: zone};
}
onClickRating(){
window['AppComponent'].zone.run(() => {window['AppComponent'].component.yourFunctionName();});
}
}