【问题标题】:Getting form state from child to parent controller从子控制器获取表单状态到父控制器
【发布时间】:2014-06-30 19:46:48
【问题描述】:

我是 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"
  })

【问题讨论】:

    标签: javascript angularjs


    【解决方案1】:

    没有内置方法可以轻松地从父控制器访问子控制器的状态。这也不是一个好的做法——父控制器不应该关心它有什么子控制器。

    相反的方法很简单,这可能是最简单和最干净的方法:

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

    例如:

    /* 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()@987654324 @) 等)。

    【讨论】:

      【解决方案2】:

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

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

      您不需要去创建可以使用价值提供者的服务。

      这种模式的好处是,您可以减少两个控制器之间的耦合,它们不相互依赖或共享知识,他们只知道他们应该拥有一个服务,该服务向他们提供来自孩子的信息,或者他们应该拥有的信息他们必须放置数据的服务。

      请提供有关提供者的角度文档以获取示例实现 https://docs.angularjs.org/guide/providers

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

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

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

      【讨论】:

      • 这是有道理的。我已经有一个工厂用于共享一些数据。但是,我假设父母和孩子的关系可能会使事情变得更容易。另外,如果我构建服务,我将如何获取/设置表单有效/无效状态的状态?有朝这个方向的指示吗?
      • 我认为您的保存和继续按钮位于错误的位置,它们需要连接到子控制器,它是子控制器,然后负责决定其内容是否正常,提交时发生的事情等。然后您的共享数据服务有效地成为您的持久性服务,一切都变得更加简单。要回答您问题的第二部分 - 我认为这两种方法都可以解决问题。
      • @Prakhar, Hargrovm:我认为人们倾向于将datastate 甚至any JS variable 混淆。服务确实很适合分享data,但是按钮的状态或者表单的有效性不是data。尽管服务是一种可行的替代方案,但我认为有更好的方法来共享状态。只是我的 2 美分...
      • 非常感谢专家系统的评论!我刚开始使用 Ng,在这个阶段弄清这种差异真是太棒了!谢谢!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-12-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多