Angular/Typescript - 在 return promise 语句中调用方法
Angular/Typescript - Making call to method within return promise statement
我在 Angular 中创建了一个组件,它读取 XML 文件并使用解析器将其显示到组件所具有的 HTML table。在解析方法中,我想通过修改读取的 XML 数据中的某些方面来更改显示数据的功能,但是每当我尝试调用将 return 更改后的数据我收到一条错误消息:
"core.js:15724 ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'CurrencyConvChange' of undefined TypeError: Cannot read property 'CurrencyConvChange' of undefined".
这是我主要组件的打字稿文件的代码:
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 方法。我对打字稿有些陌生,想知道这是否是我以前不知道的某种规则?
这与 typescript 和 promises 无关。这与 this
参考文献有关。
You define a callback function
parser.parseString(data, function(err, result)
Inside that function you try to access to this
this.CurrencyConvChange
但是那个函数里面this
指的是你定义的回调函数。不是你的组件实例。如果您想指向正确的 this
使用箭头函数来定义您的回调,如下所示:
parser.parseString(data, (err, result) => ....
或者使用如下更丑陋的解决方法:
let that = this; // outside of function
// inside your function
that.CurrencyConvChange
我有一个经常使用的愚蠢的修复程序。在您的 class 声明中:
static _this: any;
在你的构造函数中赋值:
TableofsharesComponent._this = this;
然后你可以像这样调用你的函数:
TableofsharesComponent._this.CurrencyConvChange(test_1, test_2).
如果这是个坏主意,我很想知道原因,这样我就可以更正我的代码。
我在 Angular 中创建了一个组件,它读取 XML 文件并使用解析器将其显示到组件所具有的 HTML table。在解析方法中,我想通过修改读取的 XML 数据中的某些方面来更改显示数据的功能,但是每当我尝试调用将 return 更改后的数据我收到一条错误消息:
"core.js:15724 ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'CurrencyConvChange' of undefined TypeError: Cannot read property 'CurrencyConvChange' of undefined".
这是我主要组件的打字稿文件的代码:
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 方法。我对打字稿有些陌生,想知道这是否是我以前不知道的某种规则?
这与 typescript 和 promises 无关。这与 this
参考文献有关。
You define a callback function
parser.parseString(data, function(err, result)
Inside that function you try to access to
this
this.CurrencyConvChange
但是那个函数里面this
指的是你定义的回调函数。不是你的组件实例。如果您想指向正确的 this
使用箭头函数来定义您的回调,如下所示:
parser.parseString(data, (err, result) => ....
或者使用如下更丑陋的解决方法:
let that = this; // outside of function
// inside your function
that.CurrencyConvChange
我有一个经常使用的愚蠢的修复程序。在您的 class 声明中:
static _this: any;
在你的构造函数中赋值:
TableofsharesComponent._this = this;
然后你可以像这样调用你的函数:
TableofsharesComponent._this.CurrencyConvChange(test_1, test_2).
如果这是个坏主意,我很想知道原因,这样我就可以更正我的代码。