【问题标题】:On hard refresh, $rootScope disappears and cannot access current user硬刷新时,$rootScope 消失并且无法访问当前用户
【发布时间】:2016-07-14 07:10:07
【问题描述】:

我使用$rootScope 始终访问当前登录的用户。当用户向系统提交新餐点时,餐点属性以及提交它们的用户 ID 都会被存储。

这可行,但是当我用力刷新浏览器时,$rootScope.user 对象消失了。

如何防止这种情况发生?

app.js 我有:

$rootScope.user;

以下是用户登录时发生的情况:

Auth.$onAuth(function (user) {
                if (user === null) {
                    console.log("Not logged in yet");
                } else {
                    console.log("Logged in as", user.uid);
                }
                $rootScope.user = user;
        });

然后,当用户访问 AddMeal 页面时,在 AddCtrl 内我们有:

var firebaseObj = new Firebase("https://myapp.firebaseio.com/courses/");
    var fb = $firebaseArray(firebaseObj);
console.log($rootScope.user)

$scope.newMeal = {
    name: "",
    price: "",
    ingredients: "",
    description: "",
    category: "",
    cuisine: "",
    userID:""
};

$scope.submitMeal = function () {
    if (angular.equals({}, $scope.newMeal)) {
        alert("Your form is empty");
        $rootScope.notify('Your form is empty')
    } else {
        console.log($scope.newMeal);
        var name = $scope.newMeal.name;
        var price =  $scope.newMeal.price;
        var ingredients= $scope.newMeal.ingredients;
        var description = $scope.newMeal.description;
        var category= $scope.newMeal.category;
        var cuisine= $scope.newMeal.cuisine;

        fb.$add({
            name: name,
            price: price,
            ingredients: ingredients,
            description: description,
            category: category,
            cuisine: cuisine,
            userID: $rootScope.user.uid
        }).then(function(ref) {
            $scope.newMeal = {};
            console.log(ref);
        }, function(error) {
            console.log("Error:", error);
        });

        $rootScope.notify('New meal has been added!')
    }

这是我在app.js 中的run 函数:

.run(function ($ionicPlatform, $rootScope, $firebaseAuth, $firebase, $window, $ionicLoading) {
        $ionicPlatform.ready(function () {
            // Hide the accessory bar by default (remove this to show the accessory bar above the keyboard
            // for form inputs)
            if (window.cordova && window.cordova.plugins.Keyboard) {
                cordova.plugins.Keyboard.hideKeyboardAccessoryBar(true);
                cordova.plugins.Keyboard.disableScroll(true);

            }
            if (window.StatusBar) {
                // org.apache.cordova.statusbar required
                StatusBar.styleDefault();
            }

            $rootScope.show = function(text) {
                $rootScope.loading = $ionicLoading.show({
                    content: text ? text : 'Loading..',
                    animation: 'fade-in',
                    showBackdrop: true,
                    maxWidth: 200,
                    showDelay: 0
                });
            };

            $rootScope.hide = function() {
                $ionicLoading.hide();
            };

            $rootScope.notify = function(text) {
                $rootScope.show(text);
                $window.setTimeout(function() {
                    $rootScope.hide();
                }, 1999);
            };

            $rootScope.user;

        });
    })

【问题讨论】:

  • 可以使用 sessionStorage 存储用户令牌并检查用户是否在页面加载时登录

标签: angularjs ionic-framework firebase firebase-authentication


【解决方案1】:

AngularJS 作为一个 SPA 工作(here 你可以阅读一下)。关键是当页面重新加载时,与任何其他 SPA 一样,它将丢失所有数据,并且应用程序将被“rebo​​ted”。这就是您遇到此问题的原因。

有一个简单的方法可以解决它: 当应用程序加载/重新加载时,它会转到app.config(),然后再转到app.run()(如果有的话)。 因此,我为您提供的解决方案是将您的用户信息数据保存在本地存储中(就像 cookie 一样工作),然后在应用初始化时从那里请求它。

angular.module('MyApp').run(function($rootScope){
    if(!angular.isDefined($rootScope.userInfo) && localstorage.userInfo){
        // UserInfo exists in localstorate but not on $rootScope. This means the page was reloaded or the user is returning.
        $rootScope.userInfo = localstorage.userInfo;
    }else if(!angular.isDefined($rootScope.userInfo) && !localstorage.userInfo){
        // User is not logged at all. Send him back to login page
    }else if(angular.isDefined($rootScope.userInfo)){
        // User is logged in. You can run some extra validations in here.
    }
});

我假设您将用户信息保存在变量 $rootScope.userInfo

话虽如此,我强烈建议您尝试使用服务来保存您的数据,而不是保存在 $rootScope 上。 Here's 如何实现这一目标的指南。

希望这能解决您的问题。

**更新

如果您正在使用 Ionic,您可以尝试以下方法:

var myApp = angular.module('myApp', ['ionic']);
    myApp.run(function($ionicPlatform) {
        $ionicPlatform.ready(function() {
        //load your settings from localStorage or DB where you saved.
    });
});

从这个reference.

【讨论】:

  • 嗨 Gerardo,我会试试看的!仅供参考,我最初试图使用服务来获取用户 - 请参阅我发布的这个问题 - stackoverflow.com/questions/36225588/…。但是我发现由于某种原因,我想要从服务中获得的项目出现在我的控制器中的 console.log 中 $waitForAuth 之外,但不在 $waitForAuth 函数中。
  • 将全局变量保留在服务上被认为是一种很好的做法,但如果由于某种原因您遇到了麻烦,您总是可以选择最适合您的方法。只是不要对$rootScope 太苛刻,您的应用可能很难从中读取数据。
  • 嗨@Gerardo,我试图了解如何调整我的代码以适应您的代码,以及在哪里为run 函数重构我的代码,因为我不想让@987654334 之类的事情感到不安@。您介意为此调整答案吗?
  • 我更新了我的答案。希望我能在最后一次更新中回答您的问题。
猜你喜欢
  • 1970-01-01
  • 2011-01-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-07-20
  • 2018-04-25
  • 1970-01-01
相关资源
最近更新 更多