从子控制器到父控制器获取表单状态

时间:2014-06-30 19:46:49

标签: javascript angularjs

我对Angular很新,我在父控制器和子控制器之间进行通信时遇到了困难。

jsfiddle在这里 - http://jsfiddle.net/NEuJ6/35/

我正在做的是基于具有新控制器的路线加载表单模板。然而,父控制器具有“保存并继续”按钮,我无法理解如何将子项形式的更改(有效/无效状态)绑定到父项的按钮禁用状态。

简而言之,问题是获取父控制器中子控制器中表单的实时状态

我相信,这可以通过$ watch解决,但我不确定如何继续。

控制器

<div ng-controller="MainCtrl">
  <ul>
    <li><a href="#/new">New User</a></li>
    <li><a href="#/edit">Edit USer</a></li>
    <li>To continue as guest, click on submit</li>
  </ul>
  <ng-view></ng-view>
    <button ng-click="save()">Save and continue</button>
</div>

路线

app.config( function ( $routeProvider ) {
  $routeProvider
  .when('/edit', {
      templateUrl: "form.html", 
      controller: "EditController"
  })
  .when('/new', {
      templateUrl: "form.html",
      controller: "NewController"
  })
});

第二个问题是加载该过程的下一步。当用户单击“提交”并且表单有效时,在这种情况下,我想使用新模板更改ng-view。是否建议如下(在控制器中)?

if (form.$valid) {
   location.path('/next')
}

或者我应该将继续按钮设为a标记并执行类似

的操作
<a href="#/next" ng-click="validate()">Save and continue</a>

在这两种情况下,我都会添加一条新路线。

 .when('/next', {
          templateUrl: "next.html", 
          controller: "NextController"
  })

2 个答案:

答案 0 :(得分:2)

没有内置方法可以从父控制器轻松访问子控制器的状态。这也不是一个好习惯 - 父母控制者不应该关心它有什么样的儿童控制器。

另一种方法很容易,这可能是最简单,最干净的方法:

  1. 让您的父控制器定义一个属性,根据该属性启用/禁用该按钮。
  2. 是否有任何子控制器根据其内部状态(例如表单的有效性状态)修改该属性 请注意,为了让子控制器原型继承属性而不是在本地覆盖它,它不需要是原始的( more info here )。
  3. E.g:

    /* In parent-controller */
    $scope.buttonConfig = {enabled: false};
    
    /* In child-controller */
    $scope.$watch('form.$valid', function (newValue) {
        $scope.buttonConfig.enabled = !!newValue;
    });
    

    另请参阅此 modified demo


    <子> 注意:
    还有其他替代方案(例如,使用$rootScope存储应用程序范围的状态,使用服务跨控制器共享数据,使用范围消息传递( $scope.$emit() ,< strong> $scope.$on()
    )等)。

答案 1 :(得分:1)

如果你想在控制器之间进行通信,那么我认为推荐的方式是使用服务。

服务被注入到父控制器和子控制器中,然后子服务器可以有效地调用服务的setter方法将数据存储在服务中,并且父服务器可以连接到服务上的getter方法来检索数据。

您无需继续创建可以使用值提供程序的服务。

这种模式的好处是你减少了两个控制器之间的耦合,他们不相互依赖或共享知识,他们只知道他们应该有一个服务,给他们孩子的信息或他们应该有他们必须放置数据的服务。

请提供示例实现的角度文档 https://docs.angularjs.org/guide/providers

您的问题与此问题密切相关/重复

What's the correct way to communicate between controllers in AngularJS?

最初的答案围绕在角度 - 广播/发射中使用事件模型,虽然在当前版本的角度中解决了这种模式的问题,我仍然必须同意那些喜欢基于服务的解决方案的人。