【问题标题】:Return from angular factory when ionic platform ready离子平台准备好后从角工厂返回
【发布时间】:2016-04-17 12:41:50
【问题描述】:

我有一个如下的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;
  }
]);

我在我的 ui-router 解析中注入 Auth 工厂作为依赖项,但是在配置 ui-router 时,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
          });
        }
      }
    })

在注入 ui-router 之前,如何确保 Auth 工厂不为空?

我试过了-

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);
          });
      }
    ]);

但这会返回一个承诺,这使得它使用起来更加复杂。

编辑: 我在工厂中使用了 promise 来解决问题

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;
      }
    };
  }
]);

这可行,但我正在寻找更好的解决方案。

【问题讨论】:

  • 您似乎在工厂内返回了一个空对象。
  • 这就是问题所在。我只想在平台准备好后从工厂返回

标签: javascript angularjs ionic-framework ionic firebase


【解决方案1】:

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

// "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(...)

如果你想等到平台准备好再运行你的 resolve 函数,那么只需链接 Promise;这几乎就是承诺的意义所在。

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 rather than the Y

【讨论】:

  • 谢谢@Kato - Ionic 准备好后,我正处于引导角度的相同思考过程中 - 它导致内存泄漏,我不知道如何解决这个问题。我在工厂中使用承诺来解决问题,但我不确定工厂是否应该这样使用..请参阅编辑。
【解决方案2】:

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

 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);
  }
]);

不依赖离子平台本身。

【讨论】:

  • 这不起作用,因为您正在创建新的 Firebase 而没有使用平台就绪来包装它。此外,我的一些其他工厂也有同样的问题..例如我的消息工厂也被注入解析。 app.factory('Messages', function($firebaseArray, FIREBASE_URL, $ionicPlatform){ var betweenUsers = ionic.Platform.ready(function(){ var refUserMessages = new Firebase(FIREBASE_URL+"/userMessages"); betweenUsers = function(path){ return $firebaseArray(refUserMessages.child(path)); } }); return betweenUsers; });
  • 另外,我必须在准备好离子平台的情况下包装所有与 firebase 相关的调用。所以 $waitforauth 不能解决目的
  • 为什么需要将所有这些调用包装在 ready 函数中?检查例如firebase.com/docs/web/libraries/ionic/guide.html
  • 这是一个已知问题 - forum.ionicframework.com/t/ionic-firebase-stuck-loading-forever/… 我联系了 ionic 后端团队,他们建议我将所有 firebase 初始化包装在平台准备就绪中。它解决了 firebase 的问题,但我在平台准备好之前注入依赖项有问题。
  • 那么返回一个新的promise,并在ready函数中用firebase对象解决它呢?
猜你喜欢
  • 2019-02-09
  • 1970-01-01
  • 2016-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-16
  • 1970-01-01
相关资源
最近更新 更多