简体   繁体   中英

Angular Change Detection Promises - Hybrid app

We are in the process of upgrading an AngularJS project to Angular 7. We are following the suggested "hybrid" approach where both frameworks run side by side. We are running into some change detection issues with native promises. Essentially an AngularJS (Service A) service is using a "downgraded" Angular 7 service (Service B). Prior to the migration all of ServiceB's method returned $q's defer.promise. However, now that Service B is an Angular 7 service we return regular Promises, but that is not playing nicely with Change Detection.

I tried wrapping SerivceB's call in a $q promise and I see it is working fine now. However, that is not a feasible solution since ServiceA will be upgraded to an Angular 7 service down the road.

Current code

ServiceA.get = function(order) {
    //do some work
    //ServiceB is the downgraded Angular 7 service
    //now returns a native promise

   return ServiceB.getOrders(order) 
}

ServiceA.processBatch = function(order,observer) {
    ServiceA.get(order)
    .then(function(resolve) {
        //should trigger the UI update in the Controller (still Angular JS)
        observer.onComplete(resolve)
    })
    .catch(function(err) {
        observer.onError(err)
    })
}

Now it gets interesting when I wrap the ServiceB getOrders call in $qs defer, because then the UI will update

ServiceA.get = function(order) {
        //do some work
        //ServiceB is the downgraded Angular 7 service
        //now returns a native promise
       var defer = $q.defer()
       ServiceB.getOrders(order)
          .then(function(resolve) { defer.resolve(resolve)})
          .catch(function(err) { defer.reject(err);}); 

       return defer.promise;
}

I'd expect there to be no difference, but when inspecting the callstack I see that the regular promise resolve runs within the zone, but when using $qi see that a $digest is followed.

I do not understand why this is the case. This is an oversimplyfied example of the code. In reality there is more going on which is why I am not able to return a promise from processBatch

I found the issue after a few bad days at the office. The issue was that ServiceA was using a third party library. ServiceA was depending on some callbacks by that third party library, whenever those callback ran, I was not in the "angular" zone anymore. I was in the "" zone. My question was poorly stated and my dumbed down code did not include the part about the third party library. Moral of the story is to inspect the Call Stack to see if I am in the Angular zone or "root" zone. If you are in the root zone it is likely due to a third party library that uses events that are not monkey patched by Angular

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM