从Angular $ mdDialog中访问表单

时间:2017-02-01 21:59:33

标签: javascript angularjs forms angular-material mddialog

我使用$mdDialog以推荐的方式使用Angular 1.5 Material Design 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中的表单?

4 个答案:

答案 0 :(得分:4)

您需要将表单分配给Controller的Scope。通过将表单名称从fooForm更改为dialog.fooForm来完成此操作。

<form name="dialog.fooForm" ng-submit="dialog.ok()" novalidate>

答案 1 :(得分:2)

  1. 范围存在且仍然存在,无视控制器。当你使用&#39; controllerAs xxx&#39;这只是意味着 - 将我的控制器放入范围并将其命名为xxx。你可以一起使用它们:
  2. function controller($scope) {
      var vm = this;
    
      vm.click = function() {}
    
      $scope.click = function() {}
    }
    
    <button ng-click="xxx.click()" ...
    <button ng-click="click()" ...
    
    1. 现在,如果您写ng-click="whatever();smth();" angular,将使用$parse(expression)(scope)来解析此表达式。

    2. 现在你写form name="formName" - angular将使用$parse("formName").assign(scope, form);并将其置于范围内。

    3. $ parse非常聪明,可以轻松处理嵌套属性,将表单放到控制器中(如xxx):<form name="xxx.myForm"></form>

答案 2 :(得分:2)

表单未在您的控制器中定义为属性,因此您无法访问if (this.fooForm.$dirty)等表单。

但是,您可以轻松地将其传递给您的方法:

const doFoo = (fooForm) => {
    if (fooForm.$dirty) {
    ...

在html中:

ng-click="dialog.cancel(fooForm)"

答案 3 :(得分:-1)

$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");    
            }
        };  
});`