如何在AngularJS中创建全局变量

6
我有一个问题,就是当你注册后,应该会跳转到用户页面,然后会显示“欢迎”加上用户名。但是在网页上并没有显示用户名,原因我也不太清楚,请帮忙看一下这个plunkr链接:http://plnkr.co/edit/qB3Gkeq5ji1YQyy0kpGH?p=preview。希望您能提供帮助。
我需要在plunker中添加以下代码:
script.js:
var app = angular.module('LoginApp', ["firebase", "ngRoute"])

app.config(function ($routeProvider) {
    $routeProvider
      .when('/', {
        templateUrl: 'registration.html',
        controller: 'AuthCtrl'
      })
      .when('/logIn', {
        templateUrl: 'login.html',
        controller: 'AuthCtrl'
      })

      .when('/User', {
        templateUrl: "User.html",
        controller: 'AuthCtrl'
      })
      .otherwise({
        redirectTo: '/'
      });


  });


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


app.controller("AuthCtrl", ["$scope", "Auth",
  function($scope, Auth) {


      $scope.createUser = function() {

        $scope.message = null;
        $scope.error = null;
    var ref2 = new Firebase("https://uniquecoders.firebaseio.com/");
  ref2.createUser({
    email: $scope.email,
    password: $scope.password
  }, function(error, userData) {
    if (error) {
      switch (error.code) {
        case "EMAIL_TAKEN":
          alert("The new user account cannot be created because the email is already in use. Try to login");
          break;
        case "INVALID_EMAIL":
          alert("The specified email is not a valid email.");
          break;
        case "INVALID_PASSWORD":
          alert("The Specified Passowrd Is not valid.")
          break;
        default:
          alert("Error creating user:", error);
      }
    } else {
      alert("Successfully created user account with uid:", userData.uid);
      alert($scope.UserName)

      window.location.hash = "/User"
       $scope.usernames = "HEY"
    }
  });


      };

       $scope.logIn = function(){
        $scope.message = null;
        $scope.error = null;

        ref2.authWithPassword({
          "email" : $scope.logInemail,
          "password" : $scope.logInemailpassword

        }, function(error, userData){

          if(error){
            alert("Login Failed.")
            console.log(error)
          }
          else{
            alert("Logged In!")
          }

        })

      }

  /*  $scope.removeUser = function() {
      $scope.message = null;
      $scope.error = null;

      Auth.$removeUser({
        email: $scope.email,
        password: $scope.password
      }).then(function() {
        $scope.message = "User removed";
      }).catch(function(error) {
        $scope.error = error;
      });
    };*/
  }
]);

我猜你需要更多地学习关于Angular的知识:https://docs.angularjs.org/guide,重点关注服务和作用域。 - Vinícius Fagundes
@ViníciusFagundes,你能帮我吗? - amanuel2
抱歉,这种问题应该被关闭。有几种回答的方式。 - Vinícius Fagundes
3个回答

3
当您的应用程序更改路由时,它会销毁旧控制器的作用域并创建一个新作用域。即使您将同一控制器用于旧和新路由,这也会发生。
在您的Auth工厂中存储持久数据以及创建该数据的函数。
app.factory("Auth", ["$firebaseAuth",
  function($firebaseAuth) {
    var AuthObj = {};
    //Store persistent data on AuthObj
    AuthObj.ref = new Firebase("https://uniquecoders.firebaseio.com/");
    AuthObj.createUser = function(email,password) {
        AuthObj.ref.createUser(
            {email: email, password: password },
            function(error, userData) {
                if (error) {
                    //process error
                } else {
                    //store data on AuthObj
                    AuthObj.userData = userData;
                }
             }
        );
        return AuthObj.userData;
    };
    //return AuthObj which holds functions and data
    return AuthObj;
  }
]);

使用您的控制器调用这些函数并检索持久数据。

app.controller("AuthCtrl", ["$scope", "Auth",
  function($scope, Auth) {
     //retrieve userData
     $scope.userData = Auth.userData;
     $scope.createUser = function() {
          if ($scope.userData) {
              return;
          } else {
              $scope.userData =
                   //invoke function in factory
                   Auth.createUser($scope.email,$scope.password);
          };
     };
   }
]);

这样可以使数据在更改路由时保留并持久化。

我对如何将这个实现到我的代码中感到非常困惑。抱歉我很蠢。 - amanuel2
我写答案的目标是创造出对多个读者有用的东西。所以当有人搜索“AngularJS全局变量”时,他们可以得到可以使用的建议。在这种情况下,建议是将持久数据放入工厂提供程序中。要了解更多关于工厂提供程序的信息,请参阅AngularJS服务开发人员指南 - georgeawg
我理解你的意思,但是我不太明白如何将预设数据放入你的工厂。这是一个可行的示例,如果你有其他更好的方法能帮助我以后的工作,我会非常感慕。谢谢。http://plnkr.co/edit/qB3Gkeq5ji1YQyy0kpGH?p=preview - amanuel2
在我的另一个问题中,该应用程序的登录无法正常工作。我不知道为什么。 - amanuel2

2

你的代码中可能有很多需要注意的地方,但以下是一些快速而不完美的解决方案:

不要在嵌套模板中包含所有的javascript文件。任何被路由到ng-view中的内容都应该只是你想要插入该<div>中的HTML。没有CSS链接、没有脚本标签,只有通常会在页面主体中出现的HTML。

在你的注册页面上,你的用户名ng-model需要与你传递给ng-click的参数匹配。所以你需要将ng-model="userName"改为ng-model="username"来匹配ng-click="createUser(username, email, password)"

你的另一个主要问题是每次更改视图时$scope都会被覆盖,因为每个路由都有相同的控制器。因此,从概念上讲,你可能认为(由于某种原因你将其存储为复数形式的$scope.usernamesusername仍然存在于$scope中供你访问。但事实并非如此,因为每个视图都在其自己独特的Auth Controller实例上运行。最快的解决方法(因为你不知道如何实现服务)可能是将$rootScope注入到你的控制器中,然后将usernames放在$rootScope而不是$scope上(但请记住,在生产环境中使用$rootScope被认为是不好的做法),因为$rootScope将持续存在于所有控制器之间。所以你的javascript文件看起来更像这样:

app.controller("AuthCtrl", ["$scope", "$rootScope", "Auth", function($scope, $rootScope, Auth) {

然后

$scope.createUser = function(username, email, password) { $rootScope.usernames = username $scope.message = null; $scope.error = null;


从长远来看,您将希望学习如何使用服务而不是$rootScope。在短期内,您需要确保每个视图都有一个不同的控制器。 - P Ackerman
非常感谢P Ackerman。你是我的救命恩人!它起作用了!你还有其他建议吗?我正在制作一个带有登录/注册功能的待办事项列表网站。 - amanuel2
如果不介意的话,P Ackerman,您知道如何仅为特定用户实现数据吗?非常感谢! - amanuel2

1
当您导航到用户视图时,Angular会创建AuthCtrl控制器的新实例,这意味着新的作用域,因此那里没有任何值。
使用服务在控制器之间共享数据(甚至作用域)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接