Data in callback when using 'Controller as'

2019-08-08 16:18发布

I have the simplest angular controller:

tc.controller('PurchaseCtrl', function () {
    var purchase = this;
    purchase.heading = 'Premium Features';

    this.onSuccess = function (response) {
      console.log('Success', response);
      lib.alert('success', 'Success: ', 'Loaded list of available products...');
      purchase.productList = response;
    };
    this.onFail = function (response) {
      console.log('Failure', response);
    };

    console.log('google.payments.inapp.getSkuDetails');
    lib.alert('info', 'Working: ', 'Retreiving list of available products...');
    google.payments.inapp.getSkuDetails(
      {
        'parameters': {'env': 'prod'},
        'success': purchase.onSuccess,
        'failure': purchase.onFail
      });

  });

And the view:

<div class="col-md-6 main" ng-controller="PurchaseCtrl as purchase">
    {{purchase}}
</div>

This prints out:

{"heading":"Premium Features"}

I thought that when the callback returned, the view would be update with any new data. Am I missing something? The callback returns and I see the dtaa in the console.

Using the $scope pattern I think that I would use $scope.$apply to async method, but I'm not sure how to do that here.

1条回答
2楼-- · 2019-08-08 16:29

Using controllerAs does not change the way digest cycle works or anything. It is just a sugar that adds a property (with the name same as alias name when used) to the current scope with its value pointing to the controller instance reference. So you would need to manually invoke the digest cycle (using scope.$apply[Asyc]() or even with a dummy $timeout(angular.noop,0) or $q.when() etc) in this case as well. But you can avoid injecting scope by abstracting it out into an angular service and returning a promise from there, i.e

myService.$inject = ['$q'];
function myService($q){
  //pass data and use it where needed
  this.getSkuDetails = function(data){ 
     //create deferred object
     var defer = $q.defer();
     //You can even place this the global variable `google` in a 
     //constant or something an inject it for more clean code and testability.
     google.payments.inapp.getSkuDetails({
        'parameters': {'env': 'prod'},
        'success': function success(response){
            defer.resolve(response);// resolve with value
         },
        'failure': function error(response){
            defer.reject(response); //reject with value
         }
      });
     //return promise
     return defer.promise;
  }
}
//Register service as service

Now inject myService in your controller and consume it as:

   myService.getSkuDetails(data).then(function(response){
         purchase.productList = response;
   }).catch(function(error){
      //handle Error
   });
查看更多
登录 后发表回答