ng-модель внутри $ ionicPopup templateUrl не работает с областью видимости

Это мой код контроллера. Показать всплывающее окно и при нажатии кнопки сделать некоторые проверки:

UZCampusWebMapApp.controller('PlanCtrl',function($scope, $ionicModal, $ionicLoading, $ionicPopup) {

    $scope.confirmCreatePOI = function(data) {
        var myPopup = $ionicPopup.show({
            templateUrl: 'templates/pois/confirmCreatePOI.html',
            title: 'Confirmar creación de POI',
            scope: $scope,
            buttons: [
                {
                    text: '<b>Save</b>',
                    onTap: function() {
                        var invalidEmail = $scope.email.length==0 || $scope.email==null || typeof($scope.email)=='undefined';
                        if ($scope.emailChecked==true && invalidEmail) {
                            $ionicLoading.show({ template: 'Email is mandatory'});
                        }
                        else {
                            data.email = $scope.email;
                            $scope.finalSubmitCreatePOI(data);
                        }
                    }
                },
                { 
                   text: 'Cancel'
                }
            ]
        });
    };
});

Это код директивы, в котором вызывается предыдущая функция контроллера confirmCreatePOI:

    UZCampusWebMapApp.directive('formCreatePointOfInterest', function($ionicLoading) {
      return {
        restrict : 'A',
        scope: true,
        controller : function($scope) {      
          $scope.submit = function(data) {
            console.log("Submit form createpoint of interest",data);
            if($scope.createPOIform.$valid) {
              $scope.confirmCreatePOI($scope.data);
            } else {
              $ionicLoading.show({ template: 'El formulario es inválido', duration: 1500})
            }
          }
        }
      }
    });

А это мой код templateUrl:

<div id="confirm-create-poi-popup">
  <p> Text </p>
  <p> Text </p>
  <div class="list">
    <ion-checkbox ng-model="emailChecked">Receive notification</ion-checkbox>
    <label class="item item-input">
      <input type="email" ng-model="email">
    </label>
  </div>
</div>

Итак, после того, как пользователь нажал кнопку «Сохранить» (событие onTap), я хотел бы проверить, был ли введен адрес электронной почты в поле ввода.

Но когда я проверяю это с компробированием:

var invalidEmail = $scope.email.length==0 || $scope.email==null || typeof($scope.email)=='undefined';

Выражение $scope.email.length==0 возвращает ошибку, потому что адрес электронной почты не определен, поэтому свойство ng-model не работает с $scope, я не получаю никакого значения для $scope.email

Это почему? Свойство $ionicPopup $scope не работает? Неправильно используется?


person daniegarcia254    schedule 14.07.2016    source источник


Ответы (4)


Я разрешаю это с помощью this.scope.cd_ticket:

var popup = $ionicPopup.show({
  title: 'Validar Ticket',
  scope: $scope,
  template: '<input type="tel" placeholder="Digite o código do ticket"  ng-model="cd_ticket" >',
  buttons: [{
      text: '<i class="icon ion-close"></i>',
      type: 'popup-close'
    },
    {
      text: '<i class="icon ion-checkmark"></i>',
      type: 'common-btn',
      onTap: function (e) {
        return this.scope.cd_ticket;
      }
    }
  ]
}).then(function (res) {
  if (res) {
    $ionicPopup.alert({
      title: 'Alerta',
      template: 'Ticket: ' + $scope.cd_ticket + "<br>Resposta: " + res
    });
  }
  console.log(res);
});
person Raphael Ferreira    schedule 26.10.2016

Я нашел еще несколько мест, которые можно было бы улучшить :)

Ваша функция onTap должна выглядеть так:

onTap: function() {

    // CORRECTION 1 - should use this.scope instead of $scope
    var email = this.scope.email;

    // CORRECTION 2 - check for 'undefined; first, then 'null', then 'length'
    //  (if the first OR condition is unsatisfied, the rest won't be checked for, saving time and a possible error)
    var invalidEmail = typeof(email) == 'undefined' || email == null || email.length == 0 ;

    // CORRECTION 3 - Either check for existence of 'emailChecked' or initialise it to 'false' in your templateUrl
    var emailChecked = this.scope.emailChecked;
    if (emailChecked == true && invalidEmail) {
        $ionicLoading.show({ template: 'Email is mandatory' });
    } else {
        data.email = email;
        $scope.finalSubmitCreatePOI(data);
    }
}
person Abhishek Jain    schedule 15.07.2016
comment
По-прежнему не работает, та же ошибка: TypeError: Cannot read property 'email' of undefined. Я обновил свой вопрос. Функция, в которой отображается всплывающее окно, вызывается из директивы, возможно, это как-то связано с самой проблемой. - person daniegarcia254; 18.07.2016

Просмотрите код здесь: Ionic Play - Scope Issue in Ionic Popup.

Я создал переменные email и emailChecked на объекте vm в вашем контроллере $scope.

$scope.vm = {
  email: '',
  emailChecked: false
}

Рекомендуется передавать переменные, инкапсулированные в объект, здесь vm, вместо того, чтобы передавать / использовать их как примитивные типы. vm означает модель просмотра. Общие сведения об областях.

Просто предложение, вы можете показать ошибки проверки в компоненте тоста, вот тот, который я использую ionicToast вместо использования ionicLoading.

person Ritesh Jagga    schedule 15.07.2016
comment
По-прежнему не работает, та же ошибка: TypeError: Cannot read property 'email' of undefined. Я обновил свой вопрос. Функция, в которой отображается всплывающее окно, вызывается из директивы, возможно, это как-то связано с самой проблемой. - person daniegarcia254; 18.07.2016
comment
Я не вижу confirmCreatePOI метода в вашей директиве. Похоже, что вызовы методов связаны с помощью директивы. Можете ли вы совершать прямые звонки в контроллеры и избегать директивы? - person Ritesh Jagga; 19.07.2016
comment
Обновление вопроса, я скопировал неправильный код, теперь вы можете видеть, что функция confirmCreatePOI вызывается. Возможно, я мог бы найти способ избежать директивы, но если нет ... проблема остается с областью действия - person daniegarcia254; 21.07.2016
comment
Как вызывается $scope.submit в директиве? Укажите, пожалуйста, код, в котором вызывается директива formCreatePointOfInterest? - person Ritesh Jagga; 21.07.2016

Я исправил эту проблему, переместив объявление области до templateUrl.

UZCampusWebMapApp.controller('PlanCtrl', function ($scope, $ionicModal, $ionicLoading, $ionicPopup) {

  $scope.confirmCreatePOI = function (data) {
    var myPopup = $ionicPopup.show({
      scope: $scope,
      templateUrl: 'templates/pois/confirmCreatePOI.html',
      title: 'Confirmar creación de POI',
      buttons: [{
          text: '<b>Save</b>',
          onTap: function () {
            var invalidEmail = $scope.email.length == 0 || $scope.email == null || typeof ($scope.email) == 'undefined';
            if ($scope.emailChecked == true && invalidEmail) {
              $ionicLoading.show({
                template: 'Email is mandatory'
              });
            } else {
              data.email = $scope.email;
              $scope.finalSubmitCreatePOI(data);
            }
          }
        },
        {
          text: 'Cancel'
        }
      ]
    });
  };
});
person user6764492    schedule 27.08.2016