我目前正在尝试构建一个由Angular2 IHM和区块链IHM(使用EthereumJS)组成的应用程序。 我几乎所有的东西都工作,除了角2部分。 我有一个组件应该在区块链帐户上显示帐户余额。 为了实现这种平衡,我必须调用区块链后端思想Ethereum JS API,web3。
检索完此信息后,我想用余额数据更新我的组件。 不幸的是,这不起作用。
在执行Angular未处理的代码时,我发现了zone.js问题。 到目前为止,我已经尝试了几个方法来解决这个问题,您可以在此代码示例中看到:
我的组件:
import { Component, ChangeDetectionStrategy, EventEmitter, Input, Output, NgZone, ChangeDetectorRef, ApplicationRef } from '@angular/core';
import { FormBuilder, Validators } from '@angular/forms';
import template from './wallet.template.html';
import MonTierce from "../../../../../contracts/MonTierce.sol";
import { MonTierceService } from '../../services/montierce/monTierce.service';
@Component({
selector: 'wallet',
template: template,
styleUrls: ['css/wallet.css']
})
export class WalletComponent {
constructor(formBuilder: FormBuilder, changeDetect: ChangeDetectorRef, serviceTierce: MonTierceService, ngZone: NgZone, ref: ApplicationRef) {
this.currentBalance = 0;
this.currentAddress = "No address found";
this.currentAddress = serviceTierce.getDefaultAddress();
var accountInterval = setInterval(function () {
console.log("interval start");
if (web3.eth.accounts[0] !== this.currentAddress) {
console.log("update");
this.currentAddress = web3.eth.accounts[0];
changeDetect.detectChanges();
ngZone.run(() => {
serviceTierce.getBalance(this.currentAddress).subscribe(data => {
console.log(data);
this.currentBalance = web3.fromWei(data, 'ether');
console.log(this.currentBalance);
changeDetect.detectChanges();
ref.tick();
});
});
}
}, 1000);
}
}
在此组件中,我尝试每秒更新帐户余额,但即使日志显示已成功检索余额,余额也会保持为0。
我的服务:
import { Injectable, NgZone, ChangeDetectorRef} from '@angular/core';
import MonTierce from "../../../../../contracts/MonTierce.sol";
import {Observable} from 'rxjs/Observable';
@Injectable()
export class MonTierceService {
constructor(ngZone: NgZone) {
window.web3 = new Web3(web3.currentProvider);
MonTierce.setProvider(window.web3.currentProvider);
var contratTierce = MonTierce.deployed();
this._contratTierce = contratTierce;
this._ngZone = ngZone;
}
getBalance(address) {
return new Observable(obs => {
this._ngZone.run(() => {
web3.eth.getBalance(address, (error, result) => {
if(!error){
obs.next(result.toNumber());
} else {
obs.next(error);
}
});
});
});
}
getDefaultAddress(){
return web3.eth.defaultAccount;
}
getContractAddress(){
return this._contratTierce.address;
}
}
我的模板:
<div [hidden]="!errorMessage" style="text-align: center; color: white; font-weight: bold; background-color: red; padding: 3px 10px;">{{errorMessage}}</div>
<div id="panneauControle">
<div id="wallet">
<h3> Wallet </h3>
<p id="activeAccount"><span>Your current address:</span> {{currentAddress}}</p>
<p><span>Your balance :</span> {{currentBalance}} Ethers</p>
</div>
</div>
代码可能看起来有点奇怪,因为它的ES6带有一些装饰器使它看起来像打字稿。 在这里,我尝试将web3调用运行到ngZone,以在调用结束时触发applicationRef.tick()。 我也在调用后手动调用changeRef.detectChange。 最后,在绝望中,我还添加了一个ApplicationRef.tick()。
没有任何效果我的余额永远不会更新。
你能否指出我在这段代码中犯的明显错误?
我很乐意接受你能给我的任何暗示。
亲切的问候。
本杰明
答案 0 :(得分:0)
迟到但不确定,但你是否尝试更换:
var accountInterval = setInterval(function () { /*...*/ }, 1000)
使用:
var accountInterval = setInterval(() => { /*...*/ }, 1000)
看起来这并不是指组件的上下文,因为使用function关键字创建了一个新的范围。