Угловой 5 обратного вызова и это = это - PullRequest
0 голосов
/ 14 мая 2018

в моем проекте Angular 5 у меня есть некоторые проблемы с обратным вызовом из внешней библиотеки.Я загружаю его, используя

<script src="https://js.chargebee.com/v2/chargebee.js" data-cb-site="my-site"> </script>

, а затем в Angular импортирую его следующим образом:

declare var Chargebee: any;
Chargebee.init({site: "my-site"});

У меня также есть открытая переменная в моем компоненте, скажем, publicVar, которую яЯ показываю в шаблоне.

publicVar: string = 'before checkout';

У меня есть следующий метод:

subscribeToPlan() {
  var _self = this;
  var chargebeeInstance = Chargebee.getInstance();

  chargebeeInstance.openCheckout({
    hostedPage: function() {
      _self.publicVar = 'hosted-page';
      console.log('hosted-page');
    },
    success: function(hostedPageId) {
      _self.publicVar = 'success';
      console.log('success');
    },
    close: function() {
      _self.publicVar = 'closed';
      console.log('closed');
    }
  });
}

Что происходит, когда я запускаю код?

Все console.logфункции выводят правильные данные, поэтому я знаю, что обратные вызовы Charbee вызываются.Однако только hostedPage: function() {} правильно меняет мой publicVar, и в моем шаблоне написано "hosted-page".

success: function(){} и close: function(){} не будет обновлять publicVar в моем шаблоне.Я подозреваю, потому что это, в отличие от hostedPage, методов обратного вызова и self. в них имеет неправильный контекст?

Ответы [ 2 ]

0 голосов
/ 15 мая 2018

Так что я решил (или нашел решение)

Поскольку _self действительно содержал правильные данные, я подумал, что обнаружение изменений не вызывается для этих обратных вызовов. После того, как я запустил его вручную, все работает как положено.

Окончательный код и изменения:

Импорт

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

Добавьте его в конструктор:

constructor(private cd: ChangeDetectorRef)

И затем вызвать его в конце метода обратного вызова, это вручную вызовет обнаружение изменения угла и обновит рендеринг шаблона publicVar

subscribeToPlan() {
  var _self = this;
  var chargebeeInstance = Chargebee.getInstance();

  chargebeeInstance.openCheckout({
    hostedPage: function() {
      _self.publicVar = 'hosted-page';  // This is not a callback, so it just works
      console.log('hosted-page');
    },
    success: function(hostedPageId) {
      console.log('success');
      _self.publicVar = 'success';
      _self.cd.detectChanges();  // Manual change detection
    },
    close: function() {
      console.log('closed');
      _self.publicVar = 'closed';
      _self.cd.detectChanges();  // Manual change detection
    }
  });
}

Альтернативный код с использованием функций стрелок, согласно предложению Джо (https://stackoverflow.com/a/50335020/5644425)

subscribeToPlan() {
  var chargebeeInstance = Chargebee.getInstance();

  chargebeeInstance.openCheckout({
    hostedPage: () => {
      this.publicVar = 'hosted-page';
      console.log('hosted-page');
    },
    success: hostedPageId => {
      console.log('success');
      this.publicVar = 'success';
      this.cd.detectChanges();
    },
    close: () => {
      console.log('closed');
      this.publicVar = 'closed';
      this.cd.detectChanges();
    }
  });
}
0 голосов
/ 14 мая 2018

Вместо присвоения этой переменной какой-либо переменной _self вы могли бы просто использовать функции стрелок, которые не влияют на область действия this:

subscribeToPlan() {
  var chargebeeInstance = Chargebee.getInstance();

  chargebeeInstance.openCheckout({
    hostedPage: () => {
      this.publicVar = 'hosted-page';
      console.log('hosted-page');
    },
    success: hostedPageId => {
      this.publicVar = 'success';
      console.log('success');
    },
    close: () => {
      this.publicVar = 'closed';
      console.log('closed');
    }
  });
}

И без регистрации это становится еще более аккуратным:

subscribeToPlan() {
  var chargebeeInstance = Chargebee.getInstance();

  chargebeeInstance.openCheckout({
    hostedPage: () => this.publicVar = 'hosted-page',
    success: hostedPageId => this.publicVar = 'success',
    close: () => this.publicVar = 'closed'
  });
}

Хотя я думаю, что ваш код должен работать нормально.Вы присваиваете this _self и используете это, поэтому this функций не должно иметь значения.Я определенно рекомендую установить точку останова и проверить, что _self находится в этих двух функциях.

...