控制器中未定义AngularJSmodal dialog表单对象

我们有一个页面,用下面的表格打开一个模式对话框。 然而,当我们点击控制器应该处理表单动作时,表单对象是不确定的,我是太多的angular度新手了解为什么…

这是父页面控制器拥有打开模式对话框的function:

app.controller('organisationStructureController', ['$scope', ..., '$modal', function ($scope, ..., $modal) { $scope.openInvitationDialog = function (targetOrganisationId) { $modal.open({ templateUrl: 'send-invitation.html', controller: 'sendInvitationController', resolve: {$targetOrganisationId: function () { return targetOrganisationId; } } } ); }; 

在这样的页面上:

 // inside a loop over organisations <a ng-click="openInvitationDialog({{organisation.id}})">Invite new member</a> 

邀请对话框html看起来像这样:

  <div class="modal-dialog"> <div class="modal-content"> <div class="modal-header"> <!-- ... --> </div> <div class="modal-body"> <form name="invitationForm"> <div class="form-group"> <label for="email" style="color:white;">Email</label> <input type="email" class="form-control" autocomplete="off" placeholder="New member email" id="email" name="email" ng-model="invitation.email" required="true"/> <span class="error animated fadeIn" ng-show="invitationForm.email.$dirty && invitationForm.email.$error.required">Please enter an email address!</span> <span class="error animated fadeIn" ng-show="invitationForm.email.$error.email">Invalid email</span> </div> <!-- ... --> <div class="modal-footer"> <button type="button" class="btn btn-default" ng-click="cancel()">Cancel</button> <button type="submit" class="btn btn-primary" ng-click="sendInvitation()">Invite</button> </div> </form> </div> </div> </div> 

应该处理邀请的控制器是在别的地方:

  app.controller('sendInvitationController', ['$targetOrganisationId', '$scope', ..., function ($targetOrganisationId, $scope, ...) { $scope.invitation = { // ... targetOrganisation: { id: $targetOrganisationId } }; $scope.sendInvitation = function () { // $scope.invitationForm is undefined if ($scope.invitationForm.$invalid) { return false; } // send the invitation... }; }]); 

那么将窗体范围放入控制器的正确方法是什么?

也许我需要注入$modalsendInvitationController并添加sendInvitation函数吗? 但是,当我这样做,行动永远不会进入控制器。 或者我必须将处理提交操作的函数添加到$modal.open({ ...而不是引用控制器?尽pipe我更希望将sendInvitationController放在它自己的文件和作用域中。

谢谢你的帮助!

编辑

我们发现有几件事帮助我们构build了一个解决方法,并可能帮助某人回答这个问题本身:

  1. $scope.invitation对象在sendInvitationController没有定义,但保存了正确的数据,而$scope.invitationForm保持未定义状态。
  2. 在send-invitation.html中,我们可以访问$scope.invitationForm.$invalid ,并在那里进行validation: <button type="button" ng-click="sendInvitation()" ng-disabled="invitationForm.$invalid">Invite</button>

所以问题是:为什么invitationForm对象绑定到$scope失败提交时,表单模型正确绑定?

我有同样的问题,可以通过在模块控制器的范围内定义表单对象来解决它。 为了让你的代码正常工作,例如$scope.form = {}; 在您的控制器的开始,并将您的表单标签更改为<form name="form.invitation"> 。 之后$scope.form.invitation.$invalid应该被填充。

2014年11月更新 :从angular-ui-bootstrap 0.12.0开始, 0.12.0作用域与控制器的作用域合并。 没有必要做任何事情。

在0.12.0之前

要直接在您的父控制器作用域中放置invitationForm ,您需要通过以下方式绕过被拦截的作用域:

 <form name="$parent.invitationForm"> 

上面会自动在父控制器中创build表单对象。 不需要预初始化的东西,长的对象path或事件传递。 一旦打开模式,只需使用$scope.invitationForm访问它。

“为什么?”这个问题的答案 是“范围”。 你创build了一个新的范围与模式对话框隐藏范围的forms对象从你的控制器。

如果我们简化你的代码,我们大致得到以下结果:

 <div ng-ctrl="organizeCtrl"> <modal-dialog> <form name="invitationForm"> <input type="email" ng-model="invitation.email" placeholder="Enter email..." /> <input type="submit" ng-click="sendInvitation()" text="Invite!" /> <input type="button" ng-click="cancel()" text="Cancel :(" /> </form> </modal-dialog> </div> 

(这是一个非常简化的版本,它仍然应该包含所有的核心组件)。现在,我们来看看在哪里创build范围以及注入哪些范围。

 <div ng-ctrl="sendInvitationController"> <!-- scope created above with "invitation" and "sendInvitation" from sendInvitationController --> <modal-dialog> <!-- scope created above for the modal dialog transclude --> <form name="invitationForm"> <!-- add "invitationForm" to the modal dialog's scope --> <input type="email" ng-model="invitation.email" placeholder="Enter email..." /> <input type="submit" ng-click="sendInvitation()" text="Invite!" /> <input type="button" ng-click="cancel()" text="Cancel :(" /> </form> </modal-dialog> </div> 

在这里,你可以看到在<modal-dialog>元素处创build了一个新的子范围, invitationForm对象实际添加的地方。 这就是为什么你不能在sendInvitationController看到对象,但是你可以在ng-disabled的button上看到它。 如果你想能够访问<modal-dialog>元素之外的表单结构(例如在sendInvitationController ),你需要在函数调用中传递:

 <div ng-ctrl="organizeCtrl"> <modal-dialog> <form name="invitationForm"> <input type="email" ng-model="invitation.email" placeholder="Enter email..." /> <input type="submit" ng-click="sendInvitation(invitationForm)" text="Invite!" /> <input type="button" ng-click="cancel()" text="Cancel :(" /> </form> </modal-dialog> </div> 

控制器接受邀请表作为sendInvitation函数的参数:

 app.controller('sendInvitationController', ['$targetOrganisationId', '$scope', ..., function ($targetOrganisationId, $scope, ...) { $scope.invitation = { targetOrganisation: { id: $targetOrganisationId } }; $scope.sendInvitation = function (form) { if (form.$invalid) { return false; } // send the invitation... }; }]); 

@Robinfind了另一个解决scheme,特别是创build一个根目录在sendInvitationController范围内的对象,然后直接将该表单附加到该对象上,依靠Angular的范围遍历机制来find<modal-dialog>之外的范围的form对象<modal-dialog>并附上窗体对象。 请注意,如果您没有在sendInvitationController指定$scope.form = {} ,则Angular将在<modal-dialog>的作用域上为form创build一个新对象,而您仍然无法在sendInvitationController

希望这可以帮助你或其他人学习angular度范围。

我有我的工作是这样的:

 $modal.open({ templateUrl: 'send-invitation.html', controller: 'sendInvitationController', scope: $scope // <-- I added this } 

没有表单名称,没有$parent 。 我正在使用AngularUI Bootstrap版本0.12.1。

我被这个解决了这个解决scheme。

 $mdDialog.show({ locals: {alert:"display meassage"}, controller: DialogController, templateUrl: 'views/dialog.html', parent: angular.element(document.body), clickOutsideToClose:true, backdrop: true, keyboard: true, backdropClick: true, })