Angularjs在控制器之间共享方法

时间:2014-01-30 09:12:49

标签: javascript angularjs

我正在阅读关于Angular验证的this article,并认为在我自己的项目中使用它会很好。它的工作非常好,我希望在成功验证表单后扩展它访问其他控制器中的方法。我尝试了各种方法,但我似乎无法看到$ scope对象中的方法。

<!DOCTYPE html>
<html>
  <head>
    <link data-require="bootstrap-css@3.0.0" 
      data-semver="3.0.0" 
      rel="stylesheet" 
      href="//netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" />
    <script data-require="angular.js@1.0.8" 
      data-semver="1.0.8" 
      src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.8/angular.min.js"></script>
    <script src="rcSubmit.js"></script>
    <script src="loginController.js"></script>
    <script src="loginApp.js"></script>
  </head>

  <body>
    <div class="container">
      <div class="row">
        <div class="col-xs-12 col-sm-6 col-sm-offset-3">
          <h1>Simple Login Form</h1>
          <form name="loginForm" novalidate 
            ng-app="LoginApp" ng-controller="LoginController" 
            rc-submit="login()">
            <div class="form-group"
              ng-class="{'has-error': rc.loginForm.needsAttention(loginForm.username)}">
             <input class="form-control" name="username" type="text" 
              placeholder="Username" required ng-model="session.username" />
             <span class="help-block" 
              ng-show="loginForm.username.$error.required">Required</span>
            </div>
            <div class="form-group"
              ng-class="{'has-error': rc.loginForm.needsAttention(loginForm.password)}">
              <input class="form-control" name="password" type="password" 
                placeholder="Password" required ng-model="session.password" />
              <span class="help-block" 
                ng-show="loginForm.password.$error.required">Required</span>
            </div>
            <div class="form-group">
              <button type="submit" class="btn btn-primary pull-right" 
                value="Login" title="Login">
                <span>Login</span>
              </button>
            </div>
          </form>
        </div>
      </div>
    </div>
  </body>
</html>

我希望有人能告诉我我为什么缺少这项工作。我已经分了一个plunkr

2 个答案:

答案 0 :(得分:44)

这样做的正确方法是使用角度服务。例如:

app.factory('svc', function () {
    var msg="original...";
    return {
        setMessage: function(x) {
            msg=x;
        },
        getMessage: function() {
            return msg;
        }
    };
});

通过这种方式,您可以在svc注入的任何控制器中访问svc内的功能:

app.controller("ctrl1",function($scope,svc,$timeout){
  $scope.someText=svc.getMessage();
  $scope.$watch("someText",function(v){
    svc.setMessage(v);
  });
});

app.controller("ctrl2",function($scope,svc){
  $scope.msg=svc.getMessage();
  $scope.$watch(svc.getMessage,function(v){
    $scope.msg=v;
  });
});

请参阅this demo plunk(我忽略了您提供的插件,因为它有很多噪音)。

修改

执行服务方法和表单验证并不真正相互关联,see plunk

修改

如果您想在另一个应用中使用一个应用的服务或控制器,只需引用主应用中的依赖关系,并在第二个应用内调用主应用中定义的服务。如果您的主应用程序名为demoApp1,那么您可以在dempApp2中创建另一个名为demoApp1且引用demoApp2的应用,并使用demoApp1demoApp2中定义的所有服务{1}}。请参阅插件我已更新它以演示您的要求。

答案 1 :(得分:3)

您在两个控制器之间进行通信的最佳方法是使用事件。

Scope Documentation

在此结帐中$on$broadcast$emit

在一般用例中,angular.element(catapp).scope()的使用被设计为在角度控制器之外使用,就像在jquery事件中一样。

理想情况下,您可以在控制器1中将事件写为:

$scope.$on("myEvent", function (event, args) {
   $scope.rest_id = args.username;
   $scope.getMainCategories();
});

在第二个控制器中你只是做

$scope.initRestId = function(){
   $scope.$broadcast("myEvent", {username: $scope.user.username });
};

您可以尝试将firstApp模块作为依赖项添加到您声明secondApp的{​​{1}}。这样你就可以与其他应用程序进行通信。