控制器中未定义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... }; }]);
那么将窗体范围放入控制器的正确方法是什么?
也许我需要注入$modal
到sendInvitationController
并添加sendInvitation
函数吗? 但是,当我这样做,行动永远不会进入控制器。 或者我必须将处理提交操作的函数添加到$modal.open({ ...
而不是引用控制器?尽pipe我更希望将sendInvitationController放在它自己的文件和作用域中。
谢谢你的帮助!
编辑
我们发现有几件事帮助我们构build了一个解决方法,并可能帮助某人回答这个问题本身:
-
$scope.invitation
对象在sendInvitationController
没有定义,但保存了正确的数据,而$scope.invitationForm
保持未定义状态。 - 在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, })