是否可以从ngOnInit中的动态创建的数组更新全局数组?

时间:2017-04-12 22:16:33

标签: angular typescript amcharts

我正在使用此codepen(https://www.amcharts.com/kbase/selecting-countries-map/)。它将点击的国家/地区存储在数组中。

问题是,我需要全局可用的动态数组,所以我可以在组件之间共享它。该数组当前嵌套在ngOnInit中的函数中。

是否可以从此嵌套位置更新全局数组?我已经尝试将空数组移到函数外部,使其等于全局变量等。

地图组件

import { Component, OnInit } from '@angular/core';
import { Router, RouterModule, ActivatedRoute } from '@angular/router';
import { AmChartsService } from "amcharts3-angular2";

declare var AmCharts : any; //we must declare our AmCharts variable, like Google

@Component({
  selector: 'app-map',
  templateUrl: './map.component.html',
  styleUrls: ['./map.component.css']
})

export class MapComponent implements OnInit {

  selectedCountries: any;

  constructor()
 {}


  ngOnInit() {


    var map = AmCharts.makeChart("mapdiv",{
    type: "map",
    theme: "dark",
    projection: "mercator",
    panEventsEnabled : true,
    backgroundColor : "#535364",
    backgroundAlpha : 1,
    zoomControl: {
    zoomControlEnabled : true
    },
    dataProvider : {
    map : "worldHigh",
    getAreasFromMap : true,
    areas :
    []
    },
    areasSettings : {
    autoZoom : false,
    selectable: true,
    color : "#B4B4B7",
    colorSolid : "#84ADE9",
    selectedColor : "#84ADE9",
    outlineColor : "#666666",
    rollOverColor : "#9EC2F7",
    rollOverOutlineColor : "#000000"
  },
    listeners: [{
      "event": "clickMapObject",
      "method": function(e) {

     // Ignore any click not on area
     if (e.mapObject.objectType !== "MapArea")
       return;

     var area = e.mapObject;

     // Toggle showAsSelected
     area.showAsSelected = !area.showAsSelected;
     e.chart.returnInitialColor(area);

     // Update the list
     document.getElementById("selected").innerHTML = JSON.stringify(getSelectedCountries());

   }
 }]
});

    /**
 * Function which extracts currently selected country list.
 * Returns array of country names
 */


function getSelectedCountries() {
  var selected = [];
  for(var i = 0; i < map.dataProvider.areas.length; i++) {
    if(map.dataProvider.areas[i].showAsSelected)
      selected.push(map.dataProvider.areas[i].enTitle);
  }

  return selected;
}



}


}

2 个答案:

答案 0 :(得分:1)

我将getSelectedCountries()方法与ngOnInit()区分开来。 比定义map作为组件变量,并使用方法this.selectedCountries的结果填充getSelectedCountries()

import { Component, OnInit } from '@angular/core';
import { Router, RouterModule, ActivatedRoute } from '@angular/router';
import { AmChartsService } from "amcharts3-angular2";

declare var AmCharts: any; //we must declare our AmCharts variable, like Google

@Component({
    selector: 'app-map',
    templateUrl: './map.component.html',
    styleUrls: ['./map.component.css']
})

export class MapComponent implements OnInit {

    selectedCountries: any;
    map: any;

    constructor()
    { }


    ngOnInit() {


        this.map = AmCharts.makeChart("mapdiv", {
            type: "map",
            theme: "dark",
            projection: "mercator",
            panEventsEnabled: true,
            backgroundColor: "#535364",
            backgroundAlpha: 1,
            zoomControl: {
                zoomControlEnabled: true
            },
            dataProvider: {
                map: "worldHigh",
                getAreasFromMap: true,
                areas:
                []
            },
            areasSettings: {
                autoZoom: false,
                selectable: true,
                color: "#B4B4B7",
                colorSolid: "#84ADE9",
                selectedColor: "#84ADE9",
                outlineColor: "#666666",
                rollOverColor: "#9EC2F7",
                rollOverOutlineColor: "#000000"
            },
            listeners: [{
                "event": "clickMapObject",
                "method": (e) => {

                    // Ignore any click not on area
                    if (e.mapObject.objectType !== "MapArea")
                        return;

                    var area = e.mapObject;

                    // Toggle showAsSelected
                    area.showAsSelected = !area.showAsSelected;
                    e.chart.returnInitialColor(area);

                    // Update the list
                    let result = getSelectedCountries(this.map);
                    document.getElementById("selected").innerHTML = JSON.stringify(result );
                    this.selectedCountries = result;

                }
            }]
        });

        /**
     * Function which extracts currently selected country list.
     * Returns array of country names
     */






    }

    getSelectedCountries(map: any) {
            var selected = [];
            for (var i = 0; i < map.dataProvider.areas.length; i++) {
                if (map.dataProvider.areas[i].showAsSelected)
                    selected.push(map.dataProvider.areas[i].enTitle);
            }

            return selected;
        }


}

答案 1 :(得分:0)

最好的方法是创建服务并将其提供给您引导的主模块:

共享服务

@Injectable
export class AppService {
   sharableData: string;

   constructor(){
       this.sharableData = 'some data';
   }
}

主要引导程序组件

@Component({
  selector: 'my-app',
  template: '{{_appService.sharableData}}',
})
export class App { 

  constructor(private _appService: AppService) {}
}

@NgModule({
  imports: [ BrowserModule, FormsModule ],
  declarations: [ App, AnotherComponent ],
  bootstrap: [ App ],
  provide: [
     AppService
  ]
})
export class AppModule {}

另一个组件

@Component({
  selector: 'another-component',
  template: '{{_appService.sharableData}}',
})
export class AnotherComponent { 

  constructor(private _appService: AppService) {}
}

如您所见,在同一模块中声明了两个组件。这两个组件共享相同的AppService引用,因为它是提供的。 如果您在router-outlet内部路由了组件,也会出现这种情况。