AngularJS 1.6 和非Angular 事件处理程序
AngularJS 1.6 and non-Angular event handler
使用 AngularJS 1.6 和 braintree-web 3.6.2 Hosted Fields。我已经使用 $q 将 Braintree 回调包装在承诺中(尽管 new Promise() 也可以正常工作)。现在,我正在使用不带时间参数的 $timeout 模拟 $scope.$apply()。
这是 class 为我的服务提供的 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 之后的使用似乎不被鼓励?
如果 Angular 服务包装使用例如 DOM 事件的代码,则服务应负责确保启动摘要循环(如果需要)。
使用 $apply/$digest
仍然是正确的方法。
该服务可以简单地注入 $rootScope
并将事件处理程序功能包装在对 $apply
的调用中,使其对用户保密。
另一种方法是要求服务用户传递一个范围,而不是调用 $digest
,这将限制处理的观察者数量。然而,在我看来,由此带来的(最有可能忽略不计的)性能提升不值得增加复杂性。
虽然 $timeout
也是一种可能性,但它只会不必要地推迟执行,最后无论如何都会在 $rootScope
上调用 $apply
。
使用 AngularJS 1.6 和 braintree-web 3.6.2 Hosted Fields。我已经使用 $q 将 Braintree 回调包装在承诺中(尽管 new Promise() 也可以正常工作)。现在,我正在使用不带时间参数的 $timeout 模拟 $scope.$apply()。
这是 class 为我的服务提供的 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 之后的使用似乎不被鼓励?
如果 Angular 服务包装使用例如 DOM 事件的代码,则服务应负责确保启动摘要循环(如果需要)。
使用 $apply/$digest
仍然是正确的方法。
该服务可以简单地注入 $rootScope
并将事件处理程序功能包装在对 $apply
的调用中,使其对用户保密。
另一种方法是要求服务用户传递一个范围,而不是调用 $digest
,这将限制处理的观察者数量。然而,在我看来,由此带来的(最有可能忽略不计的)性能提升不值得增加复杂性。
虽然 $timeout
也是一种可能性,但它只会不必要地推迟执行,最后无论如何都会在 $rootScope
上调用 $apply
。