离子平台准备就绪后,从棱角分明的工厂返回

Return from angular factory when ionic platform ready

本文关键字:返回 工厂 平台 准备就绪      更新时间:2023-09-26

我有一个firebase Auth工厂,如下

app.factory("Auth", ["$firebaseAuth", "FIREBASE_URL","$ionicPlatform",
  function($firebaseAuth, FIREBASE_URL, $ionicPlatform) {
      var auth = {};
      $ionicPlatform.ready(function(){
          var ref = new Firebase(FIREBASE_URL);
          auth = $firebaseAuth(ref);
      });
      return auth;
  }
]);

我将Auth工厂注入到我的ui路由器中,解析为依赖项,但当配置ui路由器时,Auth是空的,因为平台准备好了。

app.config(function ($stateProvider, $urlRouterProvider) {
  $stateProvider
    .state('menu', {
      url: '/menu',
      abstract:true,
      cache: false,
      controller: 'MenuCtrl',
      templateUrl: 'templates/menu.html',
      resolve: {
        auth: function($state, Auth){
          //<--Auth is empty here when the app starts ----->
          return Auth.$requireAuth().catch(function(){
              $state.go('login'); //if not authenticated send back to login
          });
        }
      }
    })

如何确保Auth工厂在注入ui路由器之前不为空?

我试过这个-

app.factory("Auth", ["$firebaseAuth", "FIREBASE_URL","$ionicPlatform",
      function($firebaseAuth, FIREBASE_URL, $ionicPlatform) {
          return $ionicPlatform.ready(function(){
              var ref = new Firebase(FIREBASE_URL);
              return $firebaseAuth(ref);
          });
      }
    ]);

但这返回了一个承诺,这使得它的使用更加复杂。

编辑:我在工厂里用承诺来解决的问题

app.factory("Auth", ["$firebaseAuth", "FIREBASE_URL","$ionicPlatform","$q",
  function($firebaseAuth, FIREBASE_URL, $ionicPlatform, $q) {
    var auth = {};
    return {
      getAuth : function(){
        var d = $q.defer();
        $ionicPlatform.ready().then(function(){
          var ref = new Firebase(FIREBASE_URL);
          auth = $firebaseAuth(ref);
          d.resolve(auth);
        });
        return d.promise;
      }
    };
  }
]);

这是有效的,但我正在寻找更好的解决方案。

您不能返回{},然后期望它神奇地变成$firebaseAuth实例,后者稍后在异步函数中设置。请参阅此问题以了解一些异步教育。

// "points" the x variable to object A
var x = {};
// "points" the x variable to an instance of $firebaseAuth()
// but not before {} is returned from the function
x = $firebaseAuth(...)

如果你想等到平台准备好后再运行解析功能,那么只需将承诺链接起来;这几乎就是承诺的意义所在。

app.factory('IonicReady', function($q, $ionicFramework) {
   return $q(function(resolve, reject) {
      $ionicPlatform.ready(resolve);
   });
});

然后下定决心:

resolve: {
   auth: function($state, Auth, IonicReady){
     return IonicReady
        .then(function() {
            return Auth.$requireAuth();
        })
        .catch(function(e) {
            console.error(e);
            $state.go('login');
        });
  }
}

作为Ionic的专家,这只是引出了一个问题:为什么在Ionic准备好之前就引导Angular?为什么加载Ionic时Angular没有自动启动?在平台准备好支持之前,不执行任何路由似乎更合适,并从门口简化流程。我不知道如何执行该部分,但它似乎解决了X而不是Y。

请务必查看Firebase的官方文档和示例https://www.firebase.com/docs/web/libraries/angular/guide/user-auth.html

 resolve: {
  // controller will not be loaded until $waitForAuth resolves
  // Auth refers to our $firebaseAuth wrapper in the example above
  "currentAuth": ["Auth", function(Auth) {
    // $waitForAuth returns a promise so the resolve waits for it to complete
    return Auth.$waitForAuth();
  }]
}

你的Auth工厂可以是这样的,然后

app.factory("Auth", ["$firebaseAuth",
  function($firebaseAuth) {
    var ref = new Firebase("https://docs-sandbox.firebaseio.com");
    return $firebaseAuth(ref);
  }
]);

而不依赖于离子平台本身。