AngularJS 模态对话框表单对象在控制器中未定义
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
则保持未定义状态。- 在发送邀请中.html我们可以访问
$scope.invitationForm.$invalid
并在那里进行验证:<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 之前:
若要将invitationForm
直接放入父控制器作用域,需要通过以下方式绕过已排除的作用域:
<form name="$parent.invitationForm">
以上将在父控制器中自动创建表单对象。无需预初始化内容、长对象路径或事件传递。打开模态后,只需$scope.invitationForm
访问它即可。
为什么?"问题的答案是"范围"。您创建了一个带有模式对话框的新作用域,该对话框对控制器隐藏了作用域的表单对象。
如果我们简化您的代码,我们大致得到以下内容:
<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
对象并将表单对象附加到该对象。请注意,如果您没有在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,
})
- $routeParams在传递到新视图时未定义&控制器
- Http服务工厂将未定义的返回到Angular中的控制器
- 角度指令控制器:参数不是函数,未定义
- 注入应用程序的角度控制器未定义
- 未定义的控制器AngularJS
- 从服务返回值时$scope控制器的变量是未定义的
- 尝试通过 Angular 控制器使用 Google Geocode API 进行地理编码,值未定义
- scope() 函数在 AngularJS 控制器中返回未定义
- angular.js:13424 ReferenceError:在控制器中使用工厂方法时未定义索引
- AngularJS指令中的作用域未定义,控制器中有ajax请求
- 从html调用angularjs控制器中的一个函数,但未定义范围变量
- 未定义角度控制器
- Angularjs:由控制器中的函数返回的变量是“未定义的”
- $scope.form.$error在Angular控制器中未定义
- 在一个页面上引导多个角度应用程序会导致控制器未定义错误
- AngularJS错误 - “控制器未定义”或“未定义函数”
- 测试角度控制器:未定义控制器
- 控制器未定义
- AngularJS + ASP控制器未定义
- 控制器未定义AngularJS