【问题标题】:Angular/Typescript - Making call to method within return promise statementAngular/Typescript - 在返回承诺语句中调用方法
【发布时间】:2020-01-17 22:42:57
【问题描述】:

我在 Angular 中创建了一个组件,它读取 XML 文件并使用解析器将其显示到组件所具有的 HTML 表中。在解析方法中,我想通过修改读取的 XML 数据中的某些方面来更改显示数据的功能,但是每当我尝试调用将返回更改的数据的方法时,我都会收到错误说明:

“core.js:15724 ERROR 错误:未捕获(承诺中):TypeError:无法读取未定义的属性“CurrencyConvChange” TypeError:无法读取未定义的属性“CurrencyConvChange”。

这是我的主要组件的打字稿文件的代码:

import { Component, OnInit } from '@angular/core';
import * as xml2js from 'xml2js';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { DataStoreService } from '../../data-store.service';

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

export class TableofsharesComponent
{
  public xmlItems: any;
  new_curr_value;
  test_1 = 1;
  test_2 = 1;

  constructor(private http: HttpClient, private store: DataStoreService)
  // tslint:disable-next-line: one-line
  {
    this.loadXML(); // Runs below function when the project is started.
  }

  async CurrencyConvChange(test_1, test_2)
  {
    console.dir("recieved test 1: " + test_1);
    console.dir("recieved test 2: " + test_2);
    return 0;
  }

  // Loads the data
  loadXML()
  {
    this.http.get('assets/Shares_Data.xml',
    {
      headers: new HttpHeaders()
      .set('Content-Type', 'text/xml')
      .append('Access-Control-Allow-Methods', 'GET')
      .append('Access-Control-Allow-Origin', '*')
      // tslint:disable-next-line: max-line-length
      .append('Access-Control-Allow-Headers', 'Access-Control-Allow-Headers, Access-Control-Allow-Origin, Access-Control-Request-Method'),
      responseType: 'text'
    }).subscribe((data) => {
      this.parseXML(data).then((data) =>
      {
        this.xmlItems = data; // Assigns xmlItems data from request
      });
    });
  }

  // Manipulates the data
  async parseXML(data)
  {
    return new Promise(resolve =>
    {
      let k: string | number,
      arr = [],
      test_var,
      parser = new xml2js.Parser({trim: true, explicitArray: true});

      parser.parseString(data, function(err, result)
      {
        const obj = result.ShareList;
        // tslint:disable-next-line: forin
        for (k in obj.share)
        {
          const item = obj.share[k];
          const test_1 = item.sharePrice[0].currency[0];
          console.dir("test 1: " + test_1);

          const test_2 = item.sharePrice[0].value[0];
          console.dir("Test 2: " + test_2);

          this.CurrencyConvChange(test_1, test_2);

          arr.push
          ({
            title: item.title[0], companySymbol: item.companySymbol[0],
            numOfShares: item.numOfShares[0], lastShareUpdate: item.lastShareUpdate[0],
            currency: item.sharePrice[0].currency, value: item.sharePrice[0].value
          });
        }
        resolve(arr);
      });
    });
  }
}

我正在“this.CurrencyConvChange(test_1, test_2)”行中调用我想要的方法,并且对收到的错误感到困惑,因为我已经在其他任何方法之前定义了 CurrencyConvChange 方法。我对打字稿有点陌生,想知道这是否是我以前不知道的某种规则?

【问题讨论】:

  • 你应该考虑NOT将异步与promise混为一谈,最好二选其一并一直坚持下去。

标签: angular typescript angular-promise


【解决方案1】:

这与打字稿或承诺无关。这与this 参考有关。

你定义一个回调函数

 parser.parseString(data, function(err, result)

在该函数中,您尝试访问this

 this.CurrencyConvChange

但在该函数内部this 指的是您定义的回调函数。不适用于您的组件实例。如果您想指向正确的this,请使用箭头函数来定义您的回调,如下所示:

 parser.parseString(data, (err, result) => ....

或者使用如下更丑陋的解决方法:

let that = this; // outside of function
// inside your function
that.CurrencyConvChange 

【讨论】:

  • 啊,我现在明白了。非常感谢您的帮助。
【解决方案2】:

我有一个经常使用的愚蠢修复。在你的班级声明:

static _this: any;

在你的构造函数中赋值:

TableofsharesComponent._this = this;

然后你可以像这样调用你的函数:

TableofsharesComponent._this.CurrencyConvChange(test_1, test_2). 

如果这是一个坏主意,我很想知道原因,以便我可以更正我的代码。

【讨论】:

    猜你喜欢
    • 2018-12-02
    • 2016-06-15
    • 1970-01-01
    • 2017-12-21
    • 1970-01-01
    • 2020-04-19
    • 1970-01-01
    • 1970-01-01
    • 2015-05-29
    相关资源
    最近更新 更多