从 Angular $mdDialog 中访问表单
Access form from within Angular $mdDialog
我正在按照推荐的方式使用 Angular 1.5 Material 设计 $mdDialog
,使用 controllerAs: "dialog"
。在模板中,我有一个表单:<form name="fooForm"
。在模板中,我可以毫无问题地访问表单,例如ng-disabled="fooForm.$invalid || fooForm.$submitted"
.
但是如何从 $mdDialog
控制器中访问该表单?根据我的阅读,我希望能够做到这一点:
const doFoo = () => {
if (this.fooForm.$dirty) {
这里this
是对话框控制器
但是我得到一个错误:TypeError: Cannot read property '$dirty' of undefined
。果然,如果我在代码中放置断点,控制器就没有 fooForm
属性.
我也尝试过使用 $scope
,但是当我在代码中放置断点时 $scope
也没有 fooForm
属性。
这是我的对话框模板:
<md-dialog aria-label="FooBar">
<md-toolbar>
<div class="md-toolbar-tools">
<h2>FooBar</h2>
<span flex></span>
<md-button class="md-icon-button" ng-click="dialog.cancel()">
<md-icon>close</md-icon>
</md-button>
</div>
</md-toolbar>
<form name="fooForm" ng-submit="dialog.ok()" novalidate>
<md-dialog-content>
<div layout="column" layout-padding>
<h2 class="md-headline">Foo</h2>
<div layout="row" layout-xs="column">
...
</div>
</md-dialog-content>
<md-dialog-actions>
<md-button class="md-primary" type="submit" ng-disabled="fooForm.$invalid || fooForm.$submitted">
OK
</md-button>
<md-button ng-click="dialog.cancel()">
Cancel
</md-button>
</md-dialog-actions>
</form>
</md-dialog>
如何从对话框控制器访问 $mdDialog
中的表单?
- Scope 存在并且仍然存在,忽略 controllerAs。当您使用 'controllerAs xxx' 时,这意味着 - 将我的控制器放入范围并将其命名为 xxx。您可以将它们一起使用:
function controller($scope) {
var vm = this;
vm.click = function() {}
$scope.click = function() {}
}
<button ng-click="xxx.click()" ...
<button ng-click="click()" ...
现在如果你写 ng-click="whatever();smth();"
angular 将使用 $parse(expression)(scope)
来解析这个表达式。
现在你写 form name="formName"
-- angular 将使用 $parse("formName").assign(scope, form);
并将其放入范围。
$parse 非常聪明,可以轻松处理嵌套属性,将表单放入控制器(如 xxx):<form name="xxx.myForm"></form>
该表单在您的控制器中未定义为 属性,因此您无法像 if (this.fooForm.$dirty)
.
那样访问该表单
但是您可以轻松地将其传递给您的方法:
const doFoo = (fooForm) => {
if (fooForm.$dirty) {
...
在html中:
ng-click="dialog.cancel(fooForm)"
您需要将表单分配给控制器的范围。通过将表单名称从 fooForm
更改为 dialog.fooForm
.
来执行此操作
<form name="dialog.fooForm" ng-submit="dialog.ok()" novalidate>
在 $mdDialog
初始化时输入控制器名称。见下面的代码:
$scope.showDialog = function (ev) {
$mdDialog.show({
controller: 'myController',
templateUrl: 'template.html',
parent: angular.element(document.body),
targetEvent: ev,
clickOutsideToClose: false,
fullscreen: false // Only for -xs, -sm breakpoints.
})
.then(function (answer) {
$scope.status = 'You said the information was "' + answer + '".';
}, function () {
$scope.status = 'You cancelled the dialog.';
});
};
确保在创建单独的控制器时将控制器名称放在引号中。喜欢 controller: 'myController'
如果你想传递一个函数,那么不需要像 controller: myController,
这样的引号
在 html 模板中使用 ng-submit="ok()"
而不是 ng-submit="dialog.ok()"
。
我已经使用您的模板创建了一个示例 plnkr,它运行良好。检查 here
编辑 :`
angular.module('BlankApp', ['ngMaterial']).controller('myController', function($scope, $mdDialog) {
$scope.ok = function () {
if ($scope.fooForm.$dirty) {
// do whatever you want
$mdDialog.hide("mesage");
}
};
});`
我正在按照推荐的方式使用 Angular 1.5 Material 设计 $mdDialog
,使用 controllerAs: "dialog"
。在模板中,我有一个表单:<form name="fooForm"
。在模板中,我可以毫无问题地访问表单,例如ng-disabled="fooForm.$invalid || fooForm.$submitted"
.
但是如何从 $mdDialog
控制器中访问该表单?根据我的阅读,我希望能够做到这一点:
const doFoo = () => {
if (this.fooForm.$dirty) {
这里this
是对话框控制器
但是我得到一个错误:TypeError: Cannot read property '$dirty' of undefined
。果然,如果我在代码中放置断点,控制器就没有 fooForm
属性.
我也尝试过使用 $scope
,但是当我在代码中放置断点时 $scope
也没有 fooForm
属性。
这是我的对话框模板:
<md-dialog aria-label="FooBar">
<md-toolbar>
<div class="md-toolbar-tools">
<h2>FooBar</h2>
<span flex></span>
<md-button class="md-icon-button" ng-click="dialog.cancel()">
<md-icon>close</md-icon>
</md-button>
</div>
</md-toolbar>
<form name="fooForm" ng-submit="dialog.ok()" novalidate>
<md-dialog-content>
<div layout="column" layout-padding>
<h2 class="md-headline">Foo</h2>
<div layout="row" layout-xs="column">
...
</div>
</md-dialog-content>
<md-dialog-actions>
<md-button class="md-primary" type="submit" ng-disabled="fooForm.$invalid || fooForm.$submitted">
OK
</md-button>
<md-button ng-click="dialog.cancel()">
Cancel
</md-button>
</md-dialog-actions>
</form>
</md-dialog>
如何从对话框控制器访问 $mdDialog
中的表单?
- Scope 存在并且仍然存在,忽略 controllerAs。当您使用 'controllerAs xxx' 时,这意味着 - 将我的控制器放入范围并将其命名为 xxx。您可以将它们一起使用:
function controller($scope) { var vm = this; vm.click = function() {} $scope.click = function() {} } <button ng-click="xxx.click()" ... <button ng-click="click()" ...
现在如果你写
ng-click="whatever();smth();"
angular 将使用$parse(expression)(scope)
来解析这个表达式。现在你写
form name="formName"
-- angular 将使用$parse("formName").assign(scope, form);
并将其放入范围。$parse 非常聪明,可以轻松处理嵌套属性,将表单放入控制器(如 xxx):
<form name="xxx.myForm"></form>
该表单在您的控制器中未定义为 属性,因此您无法像 if (this.fooForm.$dirty)
.
但是您可以轻松地将其传递给您的方法:
const doFoo = (fooForm) => {
if (fooForm.$dirty) {
...
在html中:
ng-click="dialog.cancel(fooForm)"
您需要将表单分配给控制器的范围。通过将表单名称从 fooForm
更改为 dialog.fooForm
.
<form name="dialog.fooForm" ng-submit="dialog.ok()" novalidate>
在 $mdDialog
初始化时输入控制器名称。见下面的代码:
$scope.showDialog = function (ev) {
$mdDialog.show({
controller: 'myController',
templateUrl: 'template.html',
parent: angular.element(document.body),
targetEvent: ev,
clickOutsideToClose: false,
fullscreen: false // Only for -xs, -sm breakpoints.
})
.then(function (answer) {
$scope.status = 'You said the information was "' + answer + '".';
}, function () {
$scope.status = 'You cancelled the dialog.';
});
};
确保在创建单独的控制器时将控制器名称放在引号中。喜欢 controller: 'myController'
如果你想传递一个函数,那么不需要像 controller: myController,
在 html 模板中使用 ng-submit="ok()"
而不是 ng-submit="dialog.ok()"
。
我已经使用您的模板创建了一个示例 plnkr,它运行良好。检查 here
编辑 :`
angular.module('BlankApp', ['ngMaterial']).controller('myController', function($scope, $mdDialog) {
$scope.ok = function () {
if ($scope.fooForm.$dirty) {
// do whatever you want
$mdDialog.hide("mesage");
}
};
});`