簡體   English   中英

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。

謝謝你的幫助!

編輯

我們發現了一些幫助我們構建變通方法的東西,可能有助於某人自己回答問題:

  1. $scope.invitation對象在sendInvitationController未定義,但保存正確的數據,而$scope.invitationForm仍未定義。
  2. 在send-invitation.html中我們可以訪問$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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM