[英]AngularJS modal dialog form object is undefined in controller
我们有一个页面打开一个模式对话框,其形式如下所示。 然而,当我们点击应该处理表单操作的控制器时,表单对象是未定义的,我太过一个Angular新手了解为什么......
这是父页面控制器保存打开模态对话框的功能:
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({ ...
而不是引用控制器?虽然我更喜欢在自己的文件和范围中使用sendInvitationController。
谢谢你的帮助!
编辑
我们发现了一些帮助我们构建变通方法的东西,可能有助于某人自己回答问题:
$scope.invitation
对象在sendInvitationController
未定义,但保存正确的数据,而$scope.invitationForm
仍未定义。 $scope.invitationForm.$invalid
并在那里进行验证: <button type="button" ng-click="sendInvitation()" ng-disabled="invitationForm.$invalid">Invite</button>
所以,问题是:为什么的结合invitationForm
对象到$scope
,而表单模型结合correcetly失败上提交?
我有同样的问题,可以通过在模态控制器范围内定义表单对象来解决它。 为了让你的代码工作,例如, $scope.form = {};
在控制器的开头,将表单标签更改为<form name="form.invitation">
。 之后$scope.form.invitation.$invalid
应该被填充。
2014年11月更新 :从angular-ui-bootstrap开始, 0.12.0
范围与控制器的范围合并。 没有必要做任何事情。
在0.12.0之前 :
要将invitationForm
直接放在父控制器范围中,您需要以这种方式绕过transcluded范围:
<form name="$parent.invitationForm">
上面将自动在父控制器中创建表单对象。 无需预先初始化的东西,长对象路径或通过事件传递。 只需在打开模态后使用$scope.invitationForm
访问它。
“为什么?”这个问题的答案。 是“范围”。 tl; dr你用模态对话框创建了一个新的作用域,该对话框隐藏了控制器中作用域的表单对象。
如果我们简化您的代码,我们大致得到以下内容:
<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>
(这是一个非常简化的版本, 应该仍然包含所有核心组件。)现在,让我们看一下范围的创建位置以及注入的范围。
<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>
元素中创建了一个新的子作用域, 这是实际添加了invitationForm
对象的位置。 这就是为什么你不能在sendInvitationController
看到对象但你可以在ng-disabled
的按钮上看到它。 如果您希望能够访问<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...
};
}]);
@Robin确定了另一个解决方案,特别是创建一个以sendInvitationController
范围为根的对象,然后将表单直接附加到该对象,依靠Angular的范围遍历机制在<modal-dialog>
之外的范围内查找form
对象<modal-dialog>
并将表单对象附加到该表单。 请注意,如果您没有在sendInvitationController
指定$scope.form = {}
,Angular会在<modal-dialog>
的作用域上为form
创建一个新对象,但您仍然无法在sendInvitationController
。
希望这有助于您或其他人了解Angular范围。
我让我这样工作:
$modal.open({
templateUrl: 'send-invitation.html',
controller: 'sendInvitationController',
scope: $scope // <-- I added this
}
没有表格名称,没有$parent
。 我正在使用AngularUI Bootstrap版本0.12.1。
我通风报信该解决方案通过此 。
$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,
})
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.