外部librairie调用

时间:2017-02-06 21:32:38

标签: javascript angular ethereum

我目前正在尝试构建一个由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);
  }

}

https://github.com/benjaminfontaine/codelab-ethereum/blob/master/horse-bet/client/app/core/components/wallet/wallet.component.js

在此组件中,我尝试每秒更新帐户余额,但即使日志显示已成功检索余额,余额也会保持为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;
  }
}

https://github.com/benjaminfontaine/codelab-ethereum/blob/master/horse-bet/client/app/core/services/montierce/monTierce.service.js

我的模板:

<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()。

没有任何效果我的余额永远不会更新。

你能否指出我在这段代码中犯的明显错误?

我很乐意接受你能给我的任何暗示。

亲切的问候。

本杰明

1 个答案:

答案 0 :(得分:0)

迟到但不确定,但你是否尝试更换:

var accountInterval = setInterval(function () { /*...*/ }, 1000)

使用:

var accountInterval = setInterval(() => { /*...*/ }, 1000)

看起来这并不是指组件的上下文,因为使用function关键字创建了一个新的范围。