Angular 6: внешняя библиотека js и проблема привязки - PullRequest
0 голосов
/ 22 октября 2018

В моем приложении я загрузил внешнюю библиотеку "braintree.js" ... все работает правильно, но есть странное поведение, которое я не могу понять.

В моем шаблоне блокdiv загружаются в зависимости от значения переменной var (regStep): когда я вызываю внешнюю библиотеку, даже если значение regStep изменяется, шаблон не показывает изменения, если я комментирую вызов внешней библиотеки и изменяюзначение regStep, шаблон изменяется соответственно.

Я не скопировал весь код, но я уверяю, что все необходимые переменные объявлены.

Я довольно новичок в Angular, может быть, яЯ что-то теряю, но я действительно не понимаю, в чем проблема.

Это вовлеченные файлы:

component.html

<div *ngIf="regservice.regStep == 1">
   <form (ngSubmit)="regservice.savePay();
   ...tags...
   </form>
</div>
<div *ngIf="regservice.regStep == 2">
   ...tags...
</div>

regservice.ts

declare var braintree: any;

import { Injectable } from '@angular/core';
import { Router } from '@angular/router';
import { HttpClient } from '@angular/common/http';

@Injectable({
   providedIn: 'root'
})

export class RegisterService {

  constructor(public router: Router, private http: HttpClient) {}
  public regStep = 1;

public savePay() : void {

let self = this;

let client = new braintree.api.Client({clientToken: this.bt_token});

client.tokenizeCard({
  number: '',
  expirationDate: '',
  cvv : ''
}, function (err, nonce) {
  if (nonce) {
    console.log(nonce); 
    self.addPayment(nonce);
  }
});
//this.addPayment('fake-valid-nonce');
//If I uncomment the above line and comment all the others everything works perfectly
}

private addPayment(nonce) : void {  

 this.http.post(this.apiUrl+'/bt-add-payment-method/',
{
    payment_method_nonce: nonce,
    billing_address_id: this.business.braintree_customer.id,
    make_default: true

},
{
  headers:{
    'Content-Type': 'application/json',
    'Authorization': 'Bearer ' + this.token['access_token']
  }}).subscribe( {
      next : response => { console.log('RESPONSE ADD PYMNT : ',response); },
      error: err => {this.handleErrors(err); },
      complete: () => { this.forward(); },
    }); 
 }

 private forward() {
  switch (this.regStep) {
     case 1 : {
        this.regStep_value = 'Step 2 of 5';
        this.regStep++;             
    }
    break;
  }
}

ОБНОВЛЕНИЕ

Даже при использовании:

client.tokenizeCard({
  number: '',
  expirationDate: '',
  cvv : ''
}, (err, nonce) => {
    console.log(nonce); 
    this.addPayment(nonce);  
});

Проблема не устранена.Шаблон остается заблокированным для STEP == 1 блока.

Если я не позвоню new braintree и соответствующий код, все работает.

В обоих случаях я вижу консоль.log RESPONSE ADD PYMNT, поэтому в обоих случаях вызывается функция AddPayment;Также в обоих случаях вызывается функция forward.

В обоих случаях я вижу, что regStep равен 2, но

  1. , если я вызвал braintree, шаблон остается заблокированным для предыдущегоstate.

  2. Если я не вызывал Braintree, шаблон меняется сразу после изменения regStep.

Ответы [ 2 ]

0 голосов
/ 24 октября 2018

Проблема связана с асинхронной функцией, выходящей из угловой зоны.

Это решит проблему:

client.tokenizeCard({
  number: '',
  expirationDate: '',
  cvv : ''
}, (err, nonce) => {
  this.zone.run(() => { //<=== added
    console.log(nonce); 
    this.addPayment(nonce);  
  })
});

логически вам необходимо импортировать NgZone

import { NgZone } from '@angular/core';

export class RegisterService {

  constructor(private zone:NgZone ) {}
}
0 голосов
/ 22 октября 2018

Если вы хотите использовать переменные / методы компонента внутри обратного вызова, лучше использовать лямбда-функцию (=>) вместо литеральных или анонимных функций.В вашем случае вы можете использовать следующее:

(err, nonce) => {   
   if (nonce) {
       console.log(nonce); 
       this.addPayment(nonce);   
    }
}
...