AngularJS 1.6和非Angular事件处理程序

时间:2016-12-18 17:25:19

标签: angularjs angular-promise braintree angular-digest es6-class

使用AngularJS 1.6和braintree-web 3.6.2 Hosted Fields。我使用$ q将Promintree回调包含在promises中(尽管新的Promise()工作正常)。现在,我正在模拟$ scope。$ apply()使用$ timeout,没有时间参数。

以下是我的服务类的ES6代码片段:

'use strict';
import braintree from 'braintree-web';

export class Cart {
  constructor($q, $log) {
    this.$q = $q;
    this.$log = $log;
  }

  // Handle the callback as a promise
  braintreeHostedFieldsCreate(clientInstance) {
    return this.$q((resolve, reject) => {
      braintree.hostedFields.create({
        client: clientInstance,
        fields: {
          number: {
            selector: '#card-number',
            placeholder: '4111 1111 1111 1111'
          },
          cvv: {
            selector: '#cvv',
            placeholder: '123'
          },
          expirationDate: {
            selector: '#expiration-date',
            placeholder: '10/2019'
          }
        },
        styles: {
          input: {
            'font-size': '14px',
            'font-family': 'Helvetica Neue, Helvetica, Arial, sans-serif',
            color: '#555'
          },
          ':focus': {
            'border-color': '#66afe9'
          },
          'input.invalid': {
            color: 'red'
          },
          'input.valid': {
            color: 'green'
          }
        }
      }, (hostedFieldsErr, hostedFieldsInstance) => {
        // Make event handlers run digest cycle using $timeout (simulate $scope.apply())
        hostedFieldsInstance.on('blur', event => this.$timeout(() => event));
        hostedFieldsInstance.on('focus', event => this.$timeout(() => event));
        hostedFieldsInstance.on('validityChange', event => this.$timeout(() => event));
        hostedFieldsInstance.on('empty', event => this.$timeout(() => event));
        hostedFieldsInstance.on('notEmpty', event => this.$timeout(() => event));

        // Reject or resolve the promise
        if(hostedFieldsErr) {
          this.$log.error('Not able to create the hosted fields with Braintree.', hostedFieldsErr);
          return reject(hostedFieldsErr);
        } else {
          this.hostedFieldsInstance = hostedFieldsInstance;
          return resolve(hostedFieldsInstance);
        }
      });
    });
  }

}

在这种情况下使用$ timeout是$ scope的一个很好的替代。$ apply()因为后者在AngularJS 1.5之后的使用似乎不鼓励了吗?

1 个答案:

答案 0 :(得分:1)

如果Angular服务包装了使用例如DOM事件的代码,那么确保摘要循环启动(如果需要)应由服务负责。

使用$apply/$digest仍然是执行此操作的正确方法。

该服务可以简单地注入$rootScope并将事件处理程序功能包装在$apply的调用中,并将其与用户保持黑盒子。

另一种方法是要求服务用户传递范围,而是调用$digest,这将限制处理的观察者数量。然而,在我看来,(这很可能是微不足道的)性能提升不会增加复杂性。

虽然$timeout也是可能的,但它只会不必要地推迟执行,并最终在$apply上调用$rootScope