javascript - 无法在 ionic 3 的多个页面中注入(inject)提供程序

标签 javascript android ionic3 inject provider

我有一个名为MapProvider的提供者

import { Injectable} from '@angular/core';
import { Http } from '@angular/http';
//import 'rxjs/add/operator/map';
import { GoogleMaps, GoogleMap, GoogleMapsEvent, LatLng, MarkerOptions, Marker, CameraPosition, PolylineOptions, ILatLng, Polyline } from "@ionic-native/google-maps";
import { Platform, AlertController } from "ionic-angular";
import { Storage } from '@ionic/storage';

import { MarkerProvider } from "../map/marker";
import { UserLocationProvider } from "../user/user-location";
import { Geoposition } from "@ionic-native/geolocation";
import { UserDataProvider } from "../user/user-data";
import { PolylineProvider } from "../map/polyline";

/*
  Generated class for the MapProvider provider.

  See https://angular.io/docs/ts/latest/guide/dependency-injection.html
  for more info on providers and Angular DI.
*/

declare var google;

@Injectable()
export class MapProvider {

  currentLocationMarker: Marker;
  currentOrders;

  constructor(private googleMaps: GoogleMaps, 
              public http: Http, 
              private markerProvider: MarkerProvider,
              private userLocationProvider: UserLocationProvider,
              private userData: UserDataProvider,
              private polylineProvider: PolylineProvider,
              private storage: Storage,
              private alertCtrl: AlertController) {}

  convert(data){
    return data.map(order=>({
      id : order.id,
      pick : new LatLng(order.pick_lat,order.pick_lng),
      pick_time : order.pick_ex_time,
      drop : new LatLng(order.drop_lat,order.drop_lng),
      drop_time : order.drop_ex_time
    }))
  }

  loadMap(navCtrl){

    // create a new map by passing HTMLElement
    let element: HTMLElement = document.getElementById('map');

    let map: GoogleMap = this.googleMaps.create(element);

    // listen to MAP_READY event
    // You must wait for this event to fire before adding something to the map or modifying it in anyway
    map.one(GoogleMapsEvent.MAP_READY).then(() => {

      this.getCurrentLocation(map,navCtrl)
        .then((userLocationMarker: Marker)=>{
          this.currentLocationMarker=userLocationMarker;
          console.log(userLocationMarker);

        
          // Watch User's Current Location
          // Don't forget to unsubscibe this to avoid memory leak
          let userWatchLocation=this.userLocationProvider.watchCurrentLocation();
          let watchhOptions = {
            enableHighAccuracy: true,
            timeout: 10000,
            maximumAge: 0
          };
          userWatchLocation.subscribe((position: Geoposition)=>{
            let userCurrentLatLng: LatLng = new LatLng(position.coords.latitude,position.coords.longitude);
            // Show Marker
            this.markerProvider.addMarker(map,userCurrentLatLng,'Your Current Location','user')
              .then((marker: Marker)=>{
                this.currentLocationMarker.remove();
                this.currentLocationMarker=marker;

                //this.changeDetectorRef.detectChanges();
              });

            // console.log("Befor addAllMarker");
            // console.log(this.currentOrders);
          },error=>console.warn('ERROR(' + error.code + '): ' + error.message),
          ()=>watchhOptions);
        });
      
    });
  }

  getCurrentLocation(map,navCtrl){
    return new Promise(resolve=>{
      // Get user's current location and set map's position
      let userCurrentLocation=this.userLocationProvider.getCurrentLocation();
      userCurrentLocation.then((position: Geoposition)=>{
        let userCurrentLatLng: LatLng = new LatLng(position.coords.latitude,position.coords.longitude);

        // Show Marker
        this.markerProvider.addMarker(map,userCurrentLatLng,'Your Current Location','user')
          .then((marker: Marker)=>{
            this.currentLocationMarker=marker;
            resolve(this.currentLocationMarker);

            // Fetch user session data
            this.storage.get('session').then((val) => {
              // After fetching user's location show all orders points
              let orderArray;
              this.userData.getCurrentOrders(val.id).then(data=>{
                orderArray=this.convert(data['deliveryOrders']);

                // Alert user with number of delivery orders assigned to them
                this.showAlert(orderArray.length,map);
                //alert("You have "+orderArray.length+" Delivery Orders");

                this.currentOrders=orderArray;
                data['deliveryOrders'].map(order=>{
                  // Draw route between pick up and drop points of an order
                  this.polylineProvider.drawRoute(map,order.pick_lat,order.pick_lng,order.drop_lat,order.drop_lng,this.polylineProvider);
                });
                // Show current location marker and order location
                this.markerProvider.addAllMarkers(map,this.currentOrders,navCtrl);
              });
            });
          });
        

        // create CameraPosition
        let mapPosition: CameraPosition = {
          target: userCurrentLatLng,
          zoom: 25,
          tilt: 30
        };

        // move the map's camera to position
        map.moveCamera(mapPosition);
      });
    });
  }

  public showAlert(number,map): void {
    // Disable the map
    map.setClickable(false);
    let alert = this.alertCtrl.create({
        title: 'You have '+number +' Delivery Orders',
        subTitle: '',
        buttons: [
          {
              text: 'Dismiss',
              role: 'cancel',
              handler: () => {
                  // Enable the map again
                  map.setClickable(true); 
              }
          }
        ]
    });
    // Show the alert
    alert.present();
  }
}

我已将此提供程序注入(inject)到我的 HomePage 中,如下所示

import { Component, ViewChild, ElementRef } from '@angular/core';
import { NavController, Platform, AlertController } from 'ionic-angular';
import { Geolocation } from '@ionic-native/geolocation';

import { GoogleMap, GoogleMapsEvent, LatLng, GoogleMaps, CameraPosition, MarkerOptions, Marker } from '@ionic-native/google-maps';
import { MapProvider } from "../../providers/map/map";
import { SignaturePage } from "../signature/signature";

//declare var google;
//declare var service;

@Component({
  selector: 'page-home',
  templateUrl: 'home.html'
})
export class HomePage {
  //map: GoogleMap;
 
  constructor(private mapProvider: MapProvider,public navCtrl: NavController,
    public platform: Platform, private alertCtrl: AlertController) {
    platform.ready().then(() => {
      //const mapElement=document.getElementById('map');
      //this.mapProvider.loadMap(this.navCtrl);
    });
    
  }

  ngOnInit(){
    this.mapProvider.loadMap(this.navCtrl);
  }

  openPad(){
    this.navCtrl.push(SignaturePage);
  }
}

但是当我按照如下方式在“OrderDropDetailsPage”中注入(inject)此提供程序时,出现错误

import { Component, ChangeDetectorRef } from '@angular/core';
import { NavController, NavParams, AlertController } from 'ionic-angular';
import { OrderDataProvider } from "../../providers/order/order-data";
import { ItemListPage } from "../item-list/item-list";
import { MapProvider } from "../../providers/map/map";

/**
 * Generated class for the OrderDropDetailsPage page.
 *
 * See http://ionicframework.com/docs/components/#navigation for more info
 * on Ionic pages and navigation.
 */

@Component({
  selector: 'page-order-drop-details',
  templateUrl: 'order-drop-details.html',
})
export class OrderDropDetailsPage {

  order_id;
  order_personal_data: any={};
  

  constructor(private mapProvider: MapProvider,public navCtrl: NavController, 
    public navParams: NavParams, 
    private orderDataProvider: OrderDataProvider,
    private changeDetectorRef: ChangeDetectorRef,
    private alertCtrl: AlertController) {

    this.order_id=navParams.get("order_id");

    // Get details of customer and display
    this.orderDataProvider.getDropPersonalDetails(this.order_id)
      .then(data=>{
        console.log(data);
        this.order_personal_data=data;
        // To display new changes call detectChanges()
        this.changeDetectorRef.detectChanges();
        console.log(this.order_personal_data);
      });
  }

  // Show ordered items list in another page
  showItems(){
    this.navCtrl.push(ItemListPage,{order_id : this.order_id});
  }

  // Item is dropped - update order status and save time
  dropped(){
    // Confirm user action to change status
    let alert = this.alertCtrl.create({
      title: 'Confirm Your Action',
      message: 'Your about to change the status of this order to DROPPED. Do you wish to proceed?',
      buttons: [
        {
          text: 'Cancel',
          role: 'cancel',
          handler: () => {
            console.log('Cancel clicked');
          }
        },
        {
          text: 'Update Status',
          handler: () => {
            this.orderDataProvider.updateOrderStatus(this.order_id,"DROPPED")
              .then(data=>{
                
                // Update delivery status to DROPPED in detail page
                this.order_personal_data.delivery_status='DROPPED';
                
                // To display new changes call detectChanges()
                this.changeDetectorRef.detectChanges();
                
                console.log('Dropped');
              });
          }
        }
      ]
    });
    alert.present();
  }

  ionViewDidLoad() {
    console.log('ionViewDidLoad OrderDropDetailsPage');
  }

}

错误如下

Uncaught Error: Can't resolve all parameters for OrderDropDetailsPage: (?, [object Object], [object Object], [object Object], [object Object], [object Object]).
at syntaxError (http://localhost:8100/build/vendor.js:98171:34)
at CompileMetadataResolver._getDependenciesMetadata (http://localhost:8100/build/vendor.js:111508:35)
at CompileMetadataResolver._getTypeMetadata (http://localhost:8100/build/vendor.js:111376:26)
at CompileMetadataResolver.getNonNormalizedDirectiveMetadata (http://localhost:8100/build/vendor.js:110985:24)
at CompileMetadataResolver._getEntryComponentMetadata (http://localhost:8100/build/vendor.js:111629:45)
at http://localhost:8100/build/vendor.js:111201:55
at Array.map (native)
at CompileMetadataResolver.getNgModuleMetadata (http://localhost:8100/build/vendor.js:111201:18)
at JitCompiler._loadModules (http://localhost:8100/build/vendor.js:122261:66)
at JitCompiler._compileModuleAndComponents (http://localhost:8100/build/vendor.js:122220:52)

我不知道为什么我无法在多个页面中注入(inject)此提供程序。请帮忙

最佳答案

当提供者之间存在循环依赖关系时,通常会发生这种情况。 欲了解更多详情,请参阅this

为了解决此问题,您可以在 OrderDropDetailsPage 构造函数中执行以下操作:

import { forwardRef } from '@angular/core';

constructor(@Inject(forwardRef(() => MapProvider)) private mapProvider, public navCtrl: NavController, 
    public navParams: NavParams, 
    private orderDataProvider: OrderDataProvider,
    private changeDetectorRef: ChangeDetectorRef,
    private alertCtrl: AlertController)

关于javascript - 无法在 ionic 3 的多个页面中注入(inject)提供程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45540272/

相关文章:

javascript - 更改内容并发回

javascript - 我如何在 Firebase Angularjs 中使用 $id 作为数字或新变量?

javascript - Meteor Facebook 登录错误 Accounts.LoginCancelledError : No matching login attempt found

javascript - 向对象添加动态函数

java - 以纵向捕获图像,但在目录中获取横向输出

点击事件上的android小部件

android - 如何训练 tesseract 只识别 20 到 30 位数字?

android - ionic 3 选项卡硬件后退按钮不会退出

angular - ionic native http get 返回类型错误 - 无法读取未定义的属性 'match'

css - ionic 3 Angular 样式 mydatepicker 组件