【问题标题】:Access form from within Angular $mdDialog从 Angular $mdDialog 中访问表单
【发布时间】:2017-06-18 20:06:36
【问题描述】:

我正在以推荐的方式使用 Angular 1.5 Material Design $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.fooForm ... 像往常一样
  • 啊,所以$scope 仍然与我的控制器不同?我认为使用controllerAs 以前在$scope 中的东西现在在我的控制器中。我想那部分仍然让我有点困惑。

标签: javascript angularjs forms angular-material mddialog


【解决方案1】:

您需要将表单分配给控制器的范围。为此,请将表单名称从 fooForm 更改为 dialog.fooForm

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

【讨论】:

  • 就是这样!今天终于试了一下,果然有效。谢谢!我想指出,在ng-disabled="fooForm.$invalid" 等表单代码中也必须相应地更新为ng-disabled="dialog.fooForm.$invalid"
【解决方案2】:
  1. 范围存在并且仍然存在,不管控制器。当您使用“controllerAs xxx”时,这只是意味着 - 将我的控制器放入范围并将其命名为 xxx。您可以一起使用它们:
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):&lt;form name="xxx.myForm"&gt;&lt;/form&gt;

【讨论】:

  • 但是我只是设置了一个断点并查看了$scope,那里也没有fooForm。你试过$mdDialog这个吗?
  • 我应该猜你的模板吗?或者你在哪里登录?
  • 我已将模板添加到问题中。日志无关紧要 --- 我实际上是在代码中放置断点并检查 $scope 对象。
  • 在哪里?在模板中还是在控制器中?
【解决方案3】:

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

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

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

在 html 中:

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

【讨论】:

    【解决方案4】:

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

    【讨论】:

    • 是的,这一切对我来说也已经很好了。您一定错过了这个问题的重点:从控制器访问对话框中的 HTML form
    • 如果您检查了 plnkr 链接,我已经创建了一个控制器,您可以从中访问对话框的表单。也添加那个 sn-p。
    猜你喜欢
    • 2018-05-22
    • 1970-01-01
    • 2018-01-20
    • 2017-11-27
    • 1970-01-01
    • 2018-03-30
    • 1970-01-01
    • 2018-03-03
    • 2018-04-19
    相关资源
    最近更新 更多