【问题标题】:Angular 2 - Unable to assign return value from http subscribe() method to a global variable inside componentAngular 2 - 无法将 http subscribe() 方法的返回值分配给组件内的全局变量
【发布时间】:2016-09-13 18:54:48
【问题描述】:

我正在使用 angular 2 中的 http.get 获取 JSON 文件。

recent.service.ts:

import { Http, Response } from '@angular/http';
//import { Observable } from '../../../../../../node_modules/rxjs/Observable';
import { Observable } from '../../../../../../node_modules/rxjs/Rx';
import { Injectable } from '@angular/core';



@Injectable()
export class RecentService {

    private _url = 'http://localhost:3001/api/uploadedFiles';

    constructor(private _http: Http) {


    }

    getJson() {

        return this._http.get(this._url)
            .map(res => res.json());

    }

}

recent.component.ts:

    import {Component, OnInit} from '@angular/core';
    import {CORE_DIRECTIVES, FORM_DIRECTIVES, NgClass, NgStyle} from             '@angular/common';
    import {RecentService} from './recent.service';
    import {HTTP_PROVIDERS} from '@angular/http'; 
    import {Observable} from 'rxjs/Observable';


   @Component({
    selector: 'recent',
    pipes: [],
    providers: [RecentService, HTTP_PROVIDERS],
    styleUrls: ['/app/pages/content/components/recent.styles.css'],   //might need to change reference   
    template: require('./recent.html') // `<strong>My edit page</strong>`
   })
   export class Recent implements OnInit{

      allFiles;
      public allFiles_error:Boolean = false;
      openModalWindow:boolean=false;
      images = [];
      currentImageIndex:number;
      opened:boolean=false;
      imgSrc:string;

   constructor(private _recentService: RecentService) {
       this._recentService.getJson()
           .subscribe(data => { 
             this.allFiles = data;
             console.log("allFiles: ", this.allFiles);
             console.log(this.allFiles.length);
             for(var i = 0; i < this.allFiles.length; i++) {
               this.images.push({
               thumb: this.allFiles[i].url,
               img: this.allFiles[i].url,
               description: "Image " + (i+1)
              });
             }
             console.log("Images: ", this.images);
            },
           err => { this.allFiles_error = true },
           () => console.log('Completed!')
    );

  }

  ngOnInit() {

    console.log(this.images.length);
    console.log(this.images);
    console.log(typeof this.images);
  }
    //this is the function where I want to access this.images
    openGallery(index) {
      if(!index) {
        this.currentImageIndex = 1;
      }
      this.currentImageIndex = index;
      this.opened = true;
      for (var i = 0; i < this.images.length; i++) {
         if (i === this.currentImageIndex ) {
         this.imgSrc = this.images[i].img;
         break;
       }
    }
    console.log(this.imgSrc);
  }

this.allFiles 是 JSON 对象的数组。我正在尝试将所选数据从 this.allFiles 存储到 this.images。我还想在整个组件中将 this.images 作为全局变量访问,但由于与 http.get() 的异步调用而无法这样做。我确实在我的 html 中尝试了异步管道,但这也导致了一个错误。有没有办法全局访问 this.images?

提前致谢。

【问题讨论】:

  • 要使某些东西成为“全局”,您可以创建一个具有静态成员和存储的共享组件/模块,并在所有其他组件中使用 if。

标签: json http angular get


【解决方案1】:

我对 TypeScript 和 Angular2 几乎没有经验,但我猜你的问题出在箭头函数和 this 关键字上。每当您在错误函数上使用方括号时,其中的this 就会开始引用函数本身,而不是所需的上层类。对你的错误处理也做同样的事情。

同时从你的构造函数中移除调用并使用ngOnInit

请尝试这样的事情并告诉我:

export class Recent implements OnInit{
    allFiles;
    public allFiles_error:Boolean = false;
    openModalWindow:boolean=false;
    images = [];
    currentImageIndex:number;
    opened:boolean=false;
    imgSrc:string;

    constructor(private _recentService: RecentService) { }

    ngOnInit() {
        this._recentService.getJson().subscribe(
            data => initData(data),
            err => handleError(),
            () => console.log('Completed!'));
    }

    initData(data){
        this.allFiles = data;
        console.log("allFiles: ", this.allFiles);
        console.log(this.allFiles.length);
        for(var i = 0; i < this.allFiles.length; i++) {
            this.images.push({
            thumb: this.allFiles[i].url,
            img: this.allFiles[i].url,
            description: "Image " + (i+1)
            });
        }
        console.log("Images: ", this.images);
        console.log(this.images.length);
        console.log(this.images);
        console.log(typeof this.images);
    }

    handleError() {
        this.allFiles_error = true;
    }
}

【讨论】:

  • 尝试了您的代码,但我仍然遇到 this.images 返回空数组的问题。我认为主要问题是 this.images 在填充之前返回。
  • 我看不到你在哪里返回this.images
  • 目前,我只是尝试在控制台上打印 0 的.subscribe() 方法之后将this.images.length 记录在ngOnInit() 中。最终,我需要访问我的 html 中的 this.images 以及我的组件中直接使用 'this.images` 数组的方法。
  • 那行不通。此时数组为空,因为订阅是异步操作。您可以完全访问我的 initData 函数,因为它只会在您从服务器返回所有结果时运行。
  • 我刚刚在我的模板上添加了 *ngIf="images" 以便 html 仅在定义图像时呈现。不过感谢您的帮助!
【解决方案2】:

您想在哪里访问 this.allFiles

你可以将它添加到模板中无需任何管道,因为它在 Observables 的订阅中,Angular2 知道重新渲染模板并且它会被更新。

如果您需要从组件中访问其他功能,请在 .subscribe 函数中添加函数调用。

【讨论】:

  • 在将 this.allFiles 中的选定值分配给 this.images 时,我仅在 subscribe() 方法中访问 this.allFilesthis.images.subscribe() 中按预期将值记录到控制台。当我尝试在另一个函数中迭代 this.images 时,就会出现问题。此外,我正在尝试从我的模板中调用这些函数。
  • 我已经编辑了原始帖子以显示我使用来自this.images 的值的函数之一。在控制台上,this.imgSrc 显示为未定义,可能是由于我遇到的问题。
  • 你不能直接从模板中调用这些函数,因为 this.images 还没有准备好,它会在调用订阅回调时准备好。所以这些函数应该从订阅中调用,或者如果你在模板中需要它,你需要添加一个 *ngIf 状态,它只会在订阅触发时呈现,所以当 this.images 可用时。
  • 这有帮助。我刚刚在我的模板上添加了 *ngIf="images" 以便 html 仅在定义图像时呈现。谢谢你的回答!
猜你喜欢
  • 2017-01-16
  • 2023-04-07
  • 1970-01-01
  • 1970-01-01
  • 2017-02-05
  • 2013-11-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多