我可以访问控制器中的表单吗?

Vin*_*ent 149 angularjs angular-foundation angularjs-forms

我目前正在使用以下内容.

$scope.$$childHead.customerForm[firstName], 以便:

<form name="customerForm">
  <input type="text" name="firstName" 
         ng-model="data.customer.firstName" 
         tabindex="1"  
         ng-disabled="!data.editable" 
         validationcustomer />
</form>
Run Code Online (Sandbox Code Playgroud)

但这仅适用于Chrome.现在我尝试了以下内容:

$scope.editCustomerForm[firstName], 以便:

<form name="customerForm" ng-model="editCustomerForm">
  <input type="text" name="firstName" 
         ng-model="data.customer.firstName" tabindex="1"  
         ng-disabled="!data.editable" 
         validationcustomer />
</form>
Run Code Online (Sandbox Code Playgroud)

哪个不起作用.请注意,我的表单位于Foundation选项卡中.我怎样才能访问firstName

编辑:看起来它form没有被添加到scope基础选项卡中的时间.

任何人都有这个解决方案?

slo*_*apa 207

虽然在其他评论中提到过,我认为我会为那些使用"Controller As"语法的人拼写一下:

<div ng-controller="MyController as ctrl">

<form name="ctrl.myForm">
    ...inputs
    Dirty? {{ctrl.myForm.$dirty}}

    <button ng-click="ctrl.saveChanges()">Save</button>
</form>

</div>
Run Code Online (Sandbox Code Playgroud)

然后您可以在代码中访问FormController,如:

function MyController () {
    var vm = this;
    vm.saveChanges = saveChanges;

    function saveChanges() {

       if(vm.myForm.$valid) { 
            // Save to db or whatever.
            vm.myForm.$setPristine();
       }
}
Run Code Online (Sandbox Code Playgroud)

  • "saveChanges"方法在javascript的第3行公开,还是我误解了? (2认同)
  • 这很好,因为这意味着你可以避免注入整个$ scope,这在我看来更干净 (2认同)
  • 您如何在茉莉花中测试呢?在我的规格中,vm.myForm是未定义的 (2认同)

小智 91

您可以将表单附加到父控制器中定义的某个对象.然后您甚至可以从儿童范围到达您的表格.

父控制器

$scope.forms = {};
Run Code Online (Sandbox Code Playgroud)

子范围中的一些模板

<form name="forms.form1">
</form>
Run Code Online (Sandbox Code Playgroud)

问题是,在执行控制器中的代码时,不必定义表单.所以你必须做这样的事情

$scope.$watch('forms.form1', function(form) {
  if(form) {
    // your code...
  }
});
Run Code Online (Sandbox Code Playgroud)

  • 我建议使用`var watcher = $ scope.$ watcher`并在if语句中你将执行watcher()取消绑定手表.这使它成为一次性观看,因此您在设置后不会观看每个摘要 (9认同)

小智 89

如果要将表单传递给控制器​​以进行验证,可以将其作为参数传递给处理提交的方法.使用表单名称,因此对于原始问题,它将类似于:

<button ng-click="submit(customerForm)">Save</button>
Run Code Online (Sandbox Code Playgroud)

  • 为了澄清未来的读者,如果你的表单被命名/定义类似于这个`<form name ="myform"> </ form>`,甚至``div ng-form name ="myform"> </ div> `,然后你的点击事件如下:`ng-click ="submit(myform)"`.然后,您可以在单击函数中访问Angular表单对象,如:`$ scope.submit = function(form){if(form.$ valid){`etc. (13认同)

Atu*_*ary 76

迟到的答案,但附带以下选项.它对我有用,但不确定它是否正确.

在我看来,我这样做:

<form name="formName">
    <div ng-init="setForm(formName);"></div>
</form>
Run Code Online (Sandbox Code Playgroud)

在控制器中:

$scope.setForm = function (form) {
    $scope.myForm = form;
}
Run Code Online (Sandbox Code Playgroud)

在这之后,我在我的控制器变量中得到了我的表单 $scope.myForm


Car*_*ten 22

为了能够访问控制器中的表单,必须将其添加到虚拟范围对象中.

就像是 $scope.dummy = {}

对于你的情况,这将意味着:

<form name="dummy.customerForm">
Run Code Online (Sandbox Code Playgroud)

在您的控制器中,您将能够通过以下方式访问该表单:

$scope.dummy.customerForm
Run Code Online (Sandbox Code Playgroud)

你将能够做类似的事情

$scope.dummy.customerForm.$setPristine()
Run Code Online (Sandbox Code Playgroud)

WIKI LINK

有一个 '.' 在你的模型中将确保原型继承发挥作用.所以,使用<input type="text" ng-model="someObj.prop1">而不是<input type="text" ng-model="prop1">

如果您确实需要/需要使用原语,则有两种解决方法:

1.在子范围中使用$ parent.parentScopeProperty.这将阻止子范围创建自己的属性.2.在父作用域上定义一个函数,并从子作业中调用它,将原始值传递给父作用域(并非总是可行)


小智 22

这个答案有点晚了,但我偶然发现了一个让一切变得更轻松的解决方案.

实际上,如果您使用的是controllerAs语法,则可以直接将表单名称指定给控制器,然后从"this"变量中引用它.这是我在我的代码中做到的方式:

我通过ui-router配置了控制器(但你可以随心所欲地做到这一点,即使在HTML中直接使用类似的东西<div ng-controller="someController as myCtrl">)这就是ui-router配置中的样子:

views: {
            "": {
                templateUrl: "someTemplate.html",
                controller: "someController",
                controllerAs: "myCtrl"
            }
       }
Run Code Online (Sandbox Code Playgroud)

然后在HTML中,您只需将表单名称设置为"controllerAs"."name"如下:

<ng-form name="myCtrl.someForm">
    <!-- example form code here -->
    <input name="firstName" ng-model="myCtrl.user.firstName" required>
</ng-form>
Run Code Online (Sandbox Code Playgroud)

现在你的控制器内你可以非常简单地做到这一点:

angular
.module("something")
.controller("someController",
    [
       "$scope",
        function ($scope) {
            var vm = this;
            if(vm.someForm.$valid){
              // do something
            }
    }]);
Run Code Online (Sandbox Code Playgroud)

  • 虽然这几乎与其他几个答案所提出的技术相同,但它是最好的变体,应该是可接受的答案,特别是因为现在每个人都使用控制器. (2认同)

小智 6

是的,您可以访问控制器中的表单(如文档中所述).

除非您的表单在控制器范围中定义,而是在子范围中定义.

基本上,一些角度指令(例如ng-if,ng-repeatng-include)将创建一个孤立的子范围.所有定义scope: {}属性的自定义指令也是如此.可能你的基础组件也在你的方式.

在引入简单ng-if<form>标签时,我遇到了同样的问题.

有关更多信息,请参阅以下

注意:我建议你重新写一下你的问题.您的问题的答案是肯定的,但您的问题略有不同:

我可以从控制器访问子范围中的表单吗?

答案就是:没有.