使用 AngularJS 1.6.1 (ES6 / Babel)...控制器调用一个使用 $ http.post()的服务方法,所以我认为它会自动运行摘要。不得不添加$ timeout来强制它(更喜欢避免$ scope。$ apply,因为这是一个Angular组件,很快就会升级到AngularJS 2。)
有没有比我做的更好的方法?然后()关闭原来的$ http.post已经运行了摘要周期?如果我不包含$ timeout,则视图中不会更新任何内容。
下订单按钮提交表格,其ngClick为$ ctrl.placeOrder(结帐):
placeOrder(form) {
if(form.$valid) {
return this.Cart.placeOrder()
.then(saleResponse => {
// Page has {{ $ctrl.pageName }} but won't update without digest cycle
this.pageName = 'Order Confirmation'; // displays confirmation
form.$setPristine(); // treat the fields as untouched
form.$submitted = false; // reset submitted state
// Force a digest to run. Why is this needed?
this.$timeout(() => this.pageName);
})
.catch(saleResponse => {
form.$submitted = false;
this.errorMessage = saleResponse.message;
if(this.errorMessage.includes('card')) this.focusOnCardNumber();
});
}
}
这是Cart.placeOrder():
placeOrder() {
// braintreeHostedFieldsTokenize() is a wrapper to return new Promise for their callback-based API
return this.braintreeHostedFieldsTokenize(this.hostedFieldsInstance)
.then(this.postOrderInformation.bind(this));
}
和Cart.postOrderInformation()
postOrderInformation(payload) {
const orderInformation = {
nonceFromClient: payload.nonce,
purchaser: this.purchaser,
recipient: this.recipient,
cartItems: this.cartItems
};
return this.$http
.post('/api/order', orderInformation)
.then(orderResponse => {
this.confirmation = orderResponse.data;
if(!orderResponse.data.success) throw orderResponse.data;
return this.confirmation;
});
}
关于我可能出错的地方的任何想法都需要使用$ timeout?我的假设是$ http.post的then()将自己运行摘要周期,因为它是AngularJS。提前谢谢。
答案 0 :(得分:2)
我的想法是.then
Cart.placeOrder()
方法正在Angular $ q服务库/队列外部的promise库/队列上执行。尝试使用$q.when
将其移至$ q服务:
placeOrder(form) {
if(form.$valid) {
//return this.Cart.placeOrder()
var promise = this.Cart.placeOrder();
return $q.when(promise)
.then(saleResponse => {
// Page has {{ $ctrl.pageName }} but won't update without digest cycle
this.pageName = 'Order Confirmation'; // displays confirmation
form.$setPristine(); // treat the fields as untouched
form.$submitted = false; // reset submitted state
// Force a digest to run. Why is this needed?
// this.$timeout(() => this.pageName);
})
braintreeHostedFieldsTokenize()
返回的承诺不是$ q服务承诺,因此没有与Angular摘要周期集成。
$ q.when
将可能是值的对象或(第三方)随后的承诺包含到
$q
承诺中。当您处理可能会或可能不是承诺的对象,或者承诺来自不可信任的源时,这非常有用。
答案 1 :(得分:0)
我建议使用$ evalAsync而不是$ timeout。查看文档(https://docs.angularjs.org/api/ng/type/ $ rootScope.Scope)和此链接:AngularJS : $evalAsync vs $timeout