Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
350 views
in Technique[技术] by (71.8m points)

Typescript async/await doesnt update AngularJS view

I'm using Typescript 2.1(developer version) to transpile async/await to ES5.

I've noticed that after I change any property which is bound to view in my async function the view isn't updated with current value, so each time I have to call $scope.$apply() at the end of function.

Example async code:

async testAsync() {
     await this.$timeout(2000);
     this.text = "Changed";
     //$scope.$apply(); <-- would like to omit this
}

And new text value isn't shown in view after this.

Is there any workaround so I don't have to manually call $scope.$apply() every time?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

The answers here are correct in that AngularJS does not know about the method so you need to 'tell' Angular about any values that have been updated.

Personally I'd use $q for asynchronous behaviour instead of using await as its "The Angular way".

You can wrap non Angular methods with $q quite easily i.e. [Note this is how I wrap all Google Maps functions as they all follow this pattern of passing in a callback to be notified of completion]

function doAThing()
{
    var defer = $q.defer();
    // Note that this method takes a `parameter` and a callback function
    someMethod(parameter, (someValue) => {
        $q.resolve(someValue)
    });

    return defer.promise;
}

You can then use it like so

this.doAThing().then(someValue => {
    this.memberValue = someValue;
});

However if you do wish to continue with await there is a better way than using $apply, in this case, and that it to use $digest. Like so

async testAsync() {
   await this.$timeout(2000);
   this.text = "Changed";
   $scope.$digest(); <-- This is now much faster :)
}

$scope.$digest is better in this case because $scope.$apply will perform dirty checking (Angulars method for change detection) for all bound values on all scopes, this can be expensive performance wise - especially if you have many bindings. $scope.$digest will, however, only perform checking on bound values within the current $scope making it much more performant.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

2.1m questions

2.1m answers

60 comments

57.0k users

...