0

在我的 Angular 应用程序中,我有一个消息服务来显示我的应用程序的信息、加载和错误消息。它看起来像这样:

module.factory('msgSvc', function(){
    var current_message = '';

    return {
        message: function(){
            return current_message;
       },
       setMessage: function(msg){
            console.log('setting message: '+ msg);
            current_message = msg;
        },
        clear: function(){ current_message = null; current_style = null}
    }
});

在我看来我有

<span class="pull-left label label-warning" >{{ msg.message() }}</span>

我有一个登录控制器,当用户提交表单时,我想在发送 ajax 登录时显示“正在登录...”消息。如果出现错误,则显示错误消息。这是我的代码:

function LoginCtrl($scope, $http, msgSvc) {
   [...]
   $scope.login = function(creds) {
    console.log(creds);
    msgSvc.setMessage('Logging in...');

    $http.post('http://...',creds)
        .success(function(data){
            console.log(data);
            [...]
            msgSvc.clear();
            $location.path('/');

        })
        .error(function(data, status){
           console.log(status);
            msgSvc.setMessage('Wrong username or password.');

        });

   };
}

login()由提交表单调用,Logging in...即使调用了函数也不会显示(它出现在控制台中)。但出现错误消息。

难道我做错了什么?

编辑:登录表单

<form class="form">
    <input type="text" placeholder="Username" ng-model="loginCreds.username" required />
    <input type="password" placeholder="Password" ng-model="loginCreds.password" required />
   <button ng-click="login(loginCreds)">Login</button>
</form>

编辑2 如果它改变任何东西,在服务和实际代码中有许多控制器设置消息,显示消息的控制器($scope.msg设置变量的位置)与设置消息的控制器不同。

function BodyCtrl($scope, msgSvc) {
    $scope.msg = msgSvc;
}
4

3 回答 3

1

您的实施存在几个问题:

  1. 由于消息被设置在私有变量中,因此您需要使用$watch才能显示消息;
  2. A.factory是一个单例,因此setMessage会为所有控制器设置相同的消息。

最简单的解决方案是将控制器传递$scopesvcMsg

app.factory("msgSvc", function () {
  return function (scope) {
    var priv_scope = scope;

    this.setMessage = function (msg) {
      console.log('setting message: '+ msg);
      priv_scope.message = msg;
    };

    this.clear = function () {
      priv_scope.message = "";
    };

  };
});

在您的控制器中,您将执行以下操作:

var msg = new msgSvc($scope);

如果您确实想将消息传播到所有控制器,请使用$rootScope

app.service("msgSvc", function ($rootScope) {
    var priv_scope = $rootScope;

    this.setMessage = function (msg) {
      console.log('setting message: '+ msg);
      priv_scope.message = msg;
    };

    this.clear = function () {
      priv_scope.message = "";
    };
});

使用以下方式查看此 Plunker $rootScope
http ://plnkr.co/edit/NYEABNvjrk8diNTwc3pP?p=preview

由于 $rootScope 在 Angular 中确实是一个全局变量,所以你不应该滥用它。如果您不小心设置了$scope.messagein 控制器,也可能会出现问题。另一种方法是用于$watch检测对 的更改message

// In your controller, do:
$scope.$watch(
  function () {
    return msgSvc.message;
  },
  function () {
    $scope.message = msgSvc.message;
  }
)

这是一个使用示例$watch
http ://plnkr.co/edit/vDV2mf?p=info

于 2013-10-04T11:50:08.610 回答
0

$scope.msg在要在视图上显示值的每个位置 设置:

function LoginCtrl($scope, $http, msgSvc) {
   [...]
   $scope.msg = "";
   $scope.login = function(creds) {
    console.log(creds);
    $scope.msg = msgSvc.setMessage('Logging in...');

    $http.post('http://...',creds)
        .success(function(data){
            console.log(data);
            [...]
            $scope.msg = msgSvc.clear();
            $location.path('/');

        })
        .error(function(data, status){
           console.log(status);
            $scope.msg = msgSvc.setMessage('Wrong username or password.');

        });

   };
}

我知道您可能试图避免这种情况,但其价值的变化并没有被传播。

于 2013-10-04T10:35:28.600 回答
-1

在 error() 中添加 $apply

  function LoginCtrl($scope, $http, msgSvc) {
             [...]

        $scope.login = function(creds) {
        console.log(creds);

        msgSvc.setMessage('Logging in...');
        $scope.msg = msgSvc;



       $http.post('http://...',creds)
              .success(function(data){
                 console.log(data);
                 [...]
                 msgSvc.clear();
                 $location.path('/');
               })
              .error(function(data, status){
                   $scope.$apply(function() {
                      msgSvc.setMessage('Wrong username or password.');
                   });
            });
      };
   }

演示

于 2013-10-04T10:41:35.160 回答