简体   繁体   中英

What do I return for an Angular binded property while waiting for $onInit callbacks to complete

I have an angular service like:

appModule.factory('dataService', DataService);

DataService.$inject = ['dataContext'];

function DataService(dataContext) {
    var service = Object.create(DataService.prototype);
    service._dataContext = dataContext;
    service._details = {};
    service.$onInit();

    return service;
}

DataService.prototype = {
    $onInit: function () {
        this._dataContext.combinedQuery(DataQuery)
            .then(function (data) {
                this._details = data[0];
            }.bind(this));
    },

    Details: function () {
        return this._details;
    }    
};

The Controller consuming it is like:

DetailsController.$inject = ["dataService"];

function DetailsController(dataService) {
    this._dataService = dataService;
}

DetailsController.prototype = {
    $onInit: function () {
        this.details = this._dataService.Details;
    },

}

And the View is binding {{$DetailsController.details}} .

When running DataService.$onInit will return, the DataService.Details function return value will be bound to DetailsController.details before this._details = data[0] has been called.

What should I be returning from DataService.Details so that once this._details is set, the data is shown on the bound view?

I think it should be something like below, but I don't want to call $onInit again:

return this.$onInit()
        .then(function () {
            return this._details;
        }.bind(this));

I would try using Promises

appModule.factory('dataService', DataService);

DataService.$inject = ['dataContext'];

function DataService(dataContext) {
    DataService.prototype().then( function (err, prototype){
      if(err){
       return err;
      }
       //Else
       var service = Object.create(prototype);
       service._dataContext = dataContext;
       service._details = {};
       service.$onInit();
       if(service){
         return service;
       }
    });
}

DataService.prototype = {
  return new Promise( function( resolve, reject){
    $onInit: function () {
        this._dataContext.combinedQuery(DataQuery)
            .then(function (data) {
                this._details = data[0];
            }.bind(this));
    }

    if( this.details ){
      Details: function () {
        return resolve( this._details );
      }   
    } else {
        return reject({err: 'Unable to set details'})
    }

  });  
};

I can't guarantee if the code above works 100% since I did not build a Plunker or similar but, it really seems like it's an asynchronous issue. If this does not work the, you should wrap $on.init() into a Promise also.

Anyways, I never seen writing services/factories like you do, so I'm a bit confused about it.

Hope it helps a bit anyways.

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