【问题标题】:Angular 1.3.9 | Service does not update in controller 1, when change in controller 2角 1.3.9 |当控制器 2 发生更改时,控制器 1 中的服务未更新
【发布时间】:2015-03-24 19:28:57
【问题描述】:

一如既往地提前感谢您。我是 Angular 的新手,并试图通过一个逐渐变得复杂的教程构建一个 todoapp 来学习。

我现在面临的挑战是尝试了解设置全局变量 isLoggedIn 的最佳方式,该变量将在用户通过护照登录时更新,并且可以在控制器之间共享状态。

这是我的代码:

var todoApp = angular.module('todoApp', []);

todoApp.service('TodoFactory', function() {

this.isLoggedInGlobal = false;

});



todoApp.controller('mainController', ['$scope', '$http', 'TodoFactory', function($scope, $http, TodoFactory) {
    $scope.formData = {due: new Date()};;
    $scope.isLoggedInGlobal = TodoFactory.isLoggedInGlobal;
    $scope.todoData = {deleted: false};

        $scope.getUserTodos = function() {
        $http.get('/api/todos/users')
            .success(function(data) {
              console.log(data)
                $scope.todos = data;
                $scope.isLoggedInGlobal = true;
            })
            .error(function(data) {
                console.log('Error: ' + data);
            });
          }

    // when submitting the add form, send the text to the node API
    $scope.createTodo = function() {
        $http.post('/api/todos', $scope.formData)
            .success(function(data) {
                $scope.formData = {}; // clear the form so our user is ready to enter another
                //$scope.todos = data; no longer needed in favor of the below function
                $scope.getUserTodos();
                console.log(data);
            })
            .error(function(data) {
                console.log('Error: ' + data);
            });
    };

    // delete a todo after checking it
    $scope.deleteTodo = function(id) {
        $http.delete('/api/todos/' + id)
            .success(function(data) {
              //$scope.todos = data; no longer needed in favor of the below function
              $scope.getUserTodos();
                console.log(data);
            })
            .error(function(data) {
                console.log('Error: ' + data);
            });
    };

        $scope.markComplete = function(id) {
        $http.get('/api/todos/complete/' + id)
            .success(function(data) {
              $scope.deleted = true;
              //$scope.todos = data; no longer needed in favor of the below function
              $scope.getUserTodos();
                console.log(data);
            })
            .error(function(data) {
                console.log('Error: ' + data);
            });
    };

  }]);

todoApp.controller('userController', ['$scope', '$http', 'TodoFactory', function($scope, $http, TodoFactory) {
	$scope.loginData = {username: 'taylorackley@gmail.com', password: 'Vb578Vb578!'};
    $scope.welcome = "Hello "
    $scope.isLoggedInGlobal = TodoFactory.isLoggedInGlobal;

    // Auth Functions via passport.
        $scope.loginUser = function() {
        $http.post('/api/users/login', $scope.loginData)
            .success(function(data) {
                $scope.loginData = {}; // clear the form so our user is ready to enter another
                $scope.user = data;
                console.log($scope.isLoggedInGlobal);
                console.log(TodoFactory.isLoggedInGlobal);
                $scope.isLoggedInGlobal = true;
                TodoFactory.isLoggedInGlobal = true;
                console.log($scope.isLoggedInGlobal);
                console.log(TodoFactory.isLoggedInGlobal);
                console.log(data);
                $scope.getUserTodos()
              })

            .error(function(data) {
                console.log('Error: ' + data);
            });

    };
  • 您可以看到我将服务注入控制器的位置,并将其设置为范围变量。
  • 当在 userController 上调用登录函数时,用户控制器 $scope 变量会更新为 true...mainController 变量不会。
  • 当然,可以通过更新 mainController 中的范围变量来解决问题...但这会默认使用全局变量。
  • 我还尝试了一个简单的工厂,它既可以返回一个简单的变量,也可以以不同的方式作为函数返回。:

todoApp.factory('mainFactory', function($scope) {

  var isLoggedInGlobal = false;
  return isLoggedIn;
});
  • 我也有点困惑,因为我还两次列出了“TodoFactory”。当我从“TodoFactory”中取出第一个引用时,就在我将它作为函数传递之前,我得到了一个未定义的错误。

任何帮助将不胜感激。

【问题讨论】:

  • 最简单最干净的解决方案是here

标签: angularjs controllers factories


【解决方案1】:

与其在服务中拥有一个属性,我会拥有一个 getter 和一个 setter:

todoApp.service('loginService', function() {
    var _loggedIn;

    this.setLoggedIn = function (val) {
        _loggedIn = val;
    };

    this.isLoggedIn = function () {
        return _loggedIn;
    };
});

在您的控制器中,您无需使用范围变量,而是调用 loginService.isLoggedIn() 来检查是否有人已登录,并调用 loginService.setLoggedIn(true) 将其设置为已登录。

在您当前的代码中,控制器中的$scope.isLoggedInGlobal 不是TodoFactory.isLoggedInGlobal 的引用。当您分配给范围变量时,该值被复制。因此,您必须同时更新两者。它们是完全独立的。

【讨论】:

  • 谢谢本。如果我在模板中使用 ng-switch,我将如何引用 getter?谢谢!
  • 我会将 getter 包装在一个可以在 ng-switch on 中使用的函数中:$scope.isLoggedIn = function () { return loginService.isLoggedIn(); }
  • 谢谢 Ben,那会在控制器中正确吗?抱歉有这些问题。这非常有帮助。
  • 没问题。是的,它会进入控制器。
猜你喜欢
  • 2023-03-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-11
  • 1970-01-01
  • 2015-11-19
  • 1970-01-01
相关资源
最近更新 更多