Javascript 如何访问AngularJS中父控制器或作用域中的FormController

Javascript 如何访问AngularJS中父控制器或作用域中的FormController,javascript,angularjs,forms,angularjs-scope,Javascript,Angularjs,Forms,Angularjs Scope,我有一个包含多个表单的页面,我只想一次显示一个表单。为此,我将每个表单分成一个部分,使用Bootstrap的accordion插件,我一次只允许打开一个部分 我的标记如下所示: <a ng-click="open_section('section1')">Section 1</a> <div collapse="section1"> <form name="section1Form"> </form> </div>

我有一个包含多个表单的页面,我只想一次显示一个表单。为此,我将每个表单分成一个部分,使用Bootstrap的accordion插件,我一次只允许打开一个部分

我的标记如下所示:

<a ng-click="open_section('section1')">Section 1</a>

<div collapse="section1">
  <form name="section1Form">
  </form>
</div>

<a ng-click="open_section('section2')">Section 2</a>

<div collapse="section2">
  <form name="section2Form">
  </form>
</div>
这是因为我正在使用
ng include
?那么,在控制器中没有办法访问这些表单吗?

在“一个可以阅读”中:

<form
       [name="{string}"]>
</form>

表格的名称。如果指定,将发布表单控制器 进入相关范围,在此名称下

但是,有些指令(如)创建了一个新的作用域:

请注意,当使用ngIf删除元素时,其范围将被销毁 当元素被还原时,会创建一个新的作用域


那会是你的情况吗?如果是这样,您可以尝试将表单名称设置为“forms.section1Form”之类的名称,然后在作用域中相应地访问它。

您的控制器可能在您的表单之外,或者您正在尝试在作用域中填充表单之前获取表单


我创建了一个,它运行得很好。

因为我使用了带有
ng视图的局部视图
表单注册在我控制器的子作用域上。由于原型继承,我似乎无法从父作用域访问子作用域

也就是说,我确实通过负责打开/关闭accordion的函数将表单控制器实例传递到我的控制器中

解决方案如下:

<a ng-click="open_section('section1', section1Form)">Section 1</a>

<div collapse="section1">
  <form name="section1Form">
  </form>
</div>

<a ng-click="open_section('section2', section2Form)">Section 2</a>

<div collapse="section2">
  <form name="section2Form">
  </form>
</div>
第1节
第二节

为了处理动态表单以及相关FormController的动态位置,我使用了一个简单的指令来帮助定位包含表单的范围

解决方案:

创建一个指令,$emit与表单关联的范围:

  module.directive('formLocator', function() {
    return {
      link: function(scope) {
        scope.$emit('formLocator');
      }
    }
在标记中使用指令:

<form name="myForm" novalidate form-locator>

要从指令、控制器等访问表单。。。您可以使用ng init:

例如:

  <form name="myForm">
     <div ng-init="myLocalScopeVar=form"></div

    <input name="myField" ....>
  </form>

这类似于伟大的答案,即将表单保存到父$scope,但它不使用事件。它基本上也在做同样的事情,但开销要小一些。

关于Sunil D.为父作用域提供表单作用域的新颖解决方案(请参阅),您实际上可以从$emit调用中发送的事件对象获取表单作用域

由于至少为Angular 1.0.3,事件对象具有targetScope属性,该属性引用事件所在的作用域$emit-ed(有关事件对象属性的详细信息,请参阅$rootScope.scope#$on)

考虑到这一点,您可以将Sunil D.的指令代码简化为:

module.directive('formLocator', function() {
  return {
    link: function(scope) {
      scope.$emit('formLocator');
    }
  };
});
$scope.$on('formLocator', function(event) {
  $scope.myDeeplyNestedForm = event.targetScope.myForm;
});
模板根本不会更改:

<form name="myForm" novalidate="" form-locator>

该指令适用于您希望为其祖先之一提供范围的任何场景,而不仅仅是ngForm。在我的代码库中,我已将该指令重命名为更通用的“present”,因为考虑该指令用途的一种方法是它宣布存在一个作用域。

有一种更简单的方法,通过使用在其作用域层次结构中查找对象的角度过程在作用域层次结构中进行备份通信

这允许我们使用点符号将对象从较低的范围附加到较高的范围

在这种情况下,您需要在顶级控制器上创建一个“catcher”空对象。然后可以从较低的范围中为该捕捉器对象指定窗体对象。这是演示的一个例子

它并不完美,但如果您将这个“catcher”对象视为事件侦听器,那么我们仍然遵循标准模式

在控制器中创建一个空的catcher对象,您希望在其中引用嵌套表单

function mainController($scope){
  $scope.catcher = {

  };
 }
然后,每当声明ng form指令时,在标记本身中设置catcher.formName=formName,如下所示

<ng-form name="alpha">
          <span ng-init="catcher.alpha = alpha"></span>
          <input type="text" required="" ng-model="alphaValue" />
        </ng-form>

因为我们被分配到“catcher.”,angular将遍历作用域层次结构,并在主控制器中找到它,而不管其间有多少控制器(当然,假设它们也没有catcher对象)

以获得负责某个指令的实际
FormController
,您只需
要求
带有hat前缀的
表单
。这样可以在指令的链接功能中存储引用:

module.directive('awesomeFormChild', [function () {

    var formController;

    return {
        require: '^form',
        link: function(scope, elm, attr, ctrl) {
            formController = ctrl;
        }
    };

}])

我知道这会引起很多恐惧。。。。但我很懒,使用了以下方法(我相信这不会因为被添加为手表和每个摘要而产生巨大的开销):


{{(controller.referenceToForm==未定义&&(controller.referenceToForm=formName)!=未定义)?“”:'''}

然后我只使用
controller。referenceToForm
在我的控制器内,等等。

类似于Sunil D。解决方案,我遇到了一个类似的,但隐式设置到scope变量,即使用标记的formController,因为我不想硬编码表单名称两次:

renderFormModule.directive('formLocator', function() {
    return {
        link: function(scope, element) {
            scope.formAssociated = scope[element[0].name];
        }
    }
});
然后,视图类似于:

    <form name="testForm" ng-controller='formController as formCtrl' form-locator novalidate>


表单在任何情况下都会被命名,正如我在示例标记中所说的那样。手风琴是否可能正在创建和销毁作用域?请使用
表单进行尝试。section1Form
。仍然得到未定义的
。我的用例可能有所不同,但是在表单中添加名称会使FormController实例在我的控制器的$scope中可用。当您尝试检查$scope.section1Form时。目前还不能立即提供。您是否可以尝试在表单的某个事件上检查它,比如通过向某个元素添加ng click。如果我尝试从表单中发送它,例如使用
ng click=“something(nameOfForm)”
提交事件,我可以使用它。但是如果事件没有在表单中发生,那么我就不能。谢谢,但这只是在创建这个问题时的一个输入错误。很抱歉。我的实际代码没有
module.directive('awesomeFormChild', [function () {

    var formController;

    return {
        require: '^form',
        link: function(scope, elm, attr, ctrl) {
            formController = ctrl;
        }
    };

}])
<form name = "formName" nf-if="someCondition">

{{(controller.referenceToForm==undefined && (controller.referenceToForm=formName) != undefined)?'':''}}

</form>
renderFormModule.directive('formLocator', function() {
    return {
        link: function(scope, element) {
            scope.formAssociated = scope[element[0].name];
        }
    }
});
    <form name="testForm" ng-controller='formController as formCtrl' form-locator novalidate>