如何将带有对象的数组从提供程序传递到页面?

时间:2019-01-09 14:51:01

标签: javascript arrays angularjs json ionic-framework

我在提供程序中有一个地图结构,我必须在模板中显示地图对象的值。 我的提供商store.ts:

import { HttpClient } from '@angular/common/http';
import { HttpClientModule } from '@angular/common/http'
import { Injectable } from '@angular/core';
import 'rxjs/add/operator/map';
import { JsonStoresDataInterface } from './../../providers/stores/stores';

/*
  Generated class for the StoresProvider provider.

  See https://angular.io/guide/dependency-injection for more info on providers
  and Angular DI.
*/
@Injectable()
export class StoresProvider {

    private JsonStoresData = new Map();
    url_request = "path/to/json";


  constructor(public http: HttpClient) {
  }

getRequest(callback){
    this.JsonStoresData.clear();
    this.http.get<JsonStoresDataInterface>(this.url_request).subscribe(data => {
        var json = data.data;
        for (var store of json.stores){
          if(store.polygon_id[0] != null){
            var obj = { name: store.name,
                        description: store.description,
                        floor: store.floor,
                        image: store.pic_info.src,
                        uid: store.uid }

            this.JsonStoresData.set(store.polygon_id, obj)
        }}
        callback(this.JsonStoresData);
    });
}

 getStoresRemote(){
    return new Promise(resolve => {
      //let def_key = this.defaultKey;
      this.getRequest(function(data){
          let storeArray = [];
          storeArray = Array.from(data.values());
          storeArray.sort((a,b) => (a.name > b.name) ? 1 : ((b.name > a.name) ? -1 : 0));
          let storeName = storeArray.map(a => a.name);
          resolve(storeArray);
      });
  });

}

}

home.ts:

import { Component } from '@angular/core';
import { NavController } from 'ionic-angular';
import { Http } from '@angular/http';
import 'rxjs/add/operator/map';
import { MenuComponent } from "../../components/menu/menu";
import { StoresProvider } from './../../providers/stores/stores';

@Component({
selector: 'page-home',
templateUrl: 'home.html'
})
export class HomePage {

public buttonClicked: boolean = false;
public btnActive: string = "";
img;
description;
storeArray;

openStore(i) {
    document.getElementById('main').className += ' no-scroll';
    document.getElementById('card').className += ' active';
    this.buttonClicked = !this.buttonClicked;
    this.description =  this.storeArray[i].description;
    console.log(this.description);// Cannot read property 'description' of undefined
at 
        }

ionViewDidLoad() {
    this.storeArray = this.storesProvider.getStoresRemote();
    console.log('this.storeArray');
  }
constructor(public navCtrl: NavController, public storesProvider: StoresProvider) {
 }

}

home.html:

<ion-header>
    <menu></menu>
    <ion-title>stores</ion-title>
</ion-header>

<ion-content  no-padding>
        <ion-list class="list-card" *ngFor="let store of storeArray | async let i = index">
                <ion-item (click)="openStore(i)" >
                <span class="name">{{store.name}}</span> //got it ok 
                <span class="floor">{{store.floor}}</span>//got it ok 

                </ion-item>
        </ion-list>

</ion-content>

                <ion-card ion-fixed  id="card" class="big-card" >
                    <p>{{description}}</p> // cant get this
                </ion-card>

错误:无法读取未定义的属性“说明”

这也是我从提供者传递的数组的外观: console screenshot 可以吗?

我需要从提供者通过离子列表获取的索引中,从提供者传递的数组中获取对象值,但是也许还有其他方法可以做到这一点?

1 个答案:

答案 0 :(得分:0)

您的getStoresRemote方法返回一个Promise,并通过在模板内部使用angular的async管道来解决该Promise。因此storeArray仅在模板内部解析,而模板在控制器内部无法访问。

当您尝试执行this.storeArray[i].description时,控制器仅知道storeArray是一个承诺(不知道它实际上已在模板中解决了),因此引发错误Cannot read property 'description' of undefined

要解决此问题,您必须从模板中删除async管道,或者将整个store对象而不是openstore传递到i方法中。

解决方案1 ​​

home.ts

openStore(i) {
    document.getElementById('main').className += ' no-scroll';
    document.getElementById('card').className += ' active';
    this.buttonClicked = !this.buttonClicked;
    this.description =  this.storeArray[i].description;
    console.log(this.description);
        }

ionViewDidLoad() {
    this.storesProvider.getStoresRemote().then(data => this.storeArray = data);
  }

home.html

 <ion-list class="list-card" *ngFor="let store of storeArray let i = index">
      <ion-item (click)="openStore(i)" >
          <span class="name">{{store.name}}</span> 
          <span class="floor">{{store.floor}}</span>
      </ion-item>
 </ion-list>

解决方案2

home.html

<ion-list class="list-card" *ngFor="let store of storeArray | async let i = index">
     <ion-item (click)="openStore(store)" >
         <span class="name">{{store.name}}</span> //got it ok 
         <span class="floor">{{store.floor}}</span>//got it ok 
     </ion-item>
</ion-list>

然后更改openstore()这样的方法

openStore(store) {
    document.getElementById('main').className += ' no-scroll';
    document.getElementById('card').className += ' active';
    this.buttonClicked = !this.buttonClicked;
    this.description = store.description;
}