AngularJS摘要周期在$ http.post.then()期间没有触发(AngularJS digest cycle not firing during $http.post.then())

编程入门 行业动态 更新时间:2024-10-15 18:30:59
AngularJS摘要周期在$ http.post.then()期间没有触发(AngularJS digest cycle not firing during $http.post.then())

使用AngularJS 1.6.1 (ES6 / Babel)...控制器调用一个使用$ http.post()的服务方法,所以我认为它会自动运行摘要。 不得不添加$ timeout来强制它(更喜欢避免$ scope。$ apply,因为这是一个Angular组件,很快就会升级到AngularJS 2)。

有没有比我做的更好的方法? 那么()关闭原来的$ http.post已经运行了摘要周期? 如果我不包含$ timeout,则视图中不会更新任何内容。

下订单按钮提交一个表格,其ngClick为$ ctrl.placeOrder(checkout):

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。 提前致谢。

Using AngularJS 1.6.1 (ES6/Babel)... controller invokes a service method which uses $http.post() so I thought it would automatically run the digest. Had to add $timeout to force it (prefer to avoid $scope.$apply as this is an Angular component and will be upgrading to AngularJS 2 soon).

Is there a better approach than what I've done? Should then() off of what was originally an $http.post have run the digest cycle? If I don't include $timeout, nothing gets updated in the view.

Place Order button submits a form with its ngClick as $ctrl.placeOrder(checkout):

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(); }); } }

Here's 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)); }

and 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; }); }

Any thoughts about where I might have gone wrong necessitating the use of $timeout? My assumption was that $http.post's then() would run the digest cycle on its own since it's AngularJS. Thanks in advance.

最满意答案

我的想法是, Cart.placeOrder()的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()返回的braintreeHostedFieldsTokenize()不是$ q服务承诺,因此没有与Angular摘要循环集成。

$ q.when

将可能是值的对象或(第三方)包装成$q承诺。 当您处理可能是或可能不是promise的对象,或者promise是来自不可信任的源时,这非常有用。

- AngularJS $ q服务API参考 - $ q.when

My thought is that the .then method of Cart.placeOrder() is being performed on a promise library/queue that is external to the Angular $q Service library/queue. Try moving it to the $q Service with $q.when:

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); })

The promise returned by braintreeHostedFieldsTokenize() is not a $q Service promise and thus not integrated with the Angular digest cycle.

$q.when

Wraps an object that might be a value or a (3rd party) then-able promise into a $q promise. This is useful when you are dealing with an object that might or might not be a promise, or if the promise comes from a source that can't be trusted.

-- AngularJS $q Service API Reference - $q.when

更多推荐

本文发布于:2023-07-14 14:34:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1105126.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:周期   摘要   http   AngularJS   cycle

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!