2

У меня есть веб-приложение, которое необходимо просмотреть с ориентацией на ландшафт.

Для этого я создал функцию, которая проверяет innerWidth и innderHeight, и если ширина больше, чем высота, то счастливые дни. Это отлично работает, когда я загружаю страницу, но я также проверяю ориентацию при запуске события resize.

Так поток моего кода -

  1. После запуска вызова resize события $scope.getOrienttion()
  2. Рассчитайте текущую ориентацию и возвращает результат
  3. изменения монитора к значению $scope.getOrienttion() с использованием watch и обновить значение $scope.orientation

Этапы 1 и 2 выше, по-видимому, отлично работает, но мой watch никогда не обнаруживает изменения в $scope.getOrienttion() и запускается только при загрузке страницы. Я должен что-то делать неправильно, может кто-нибудь помочь мне найти проблему.

Вот соответствующие AngularJS -

christmasApp.controller('bodyCtrl', function($scope, $window){ 

    angular.element($window).bind('resize', function(){ 
     console.log('Event triggered'); 
     $scope.getOrientation(); 
    }); 

    $scope.getOrientation = function(){ 

     var w = $window.innerWidth, 
      h = $window.innerHeight; 
     var orientation = (w > h) ? 'landscape' : 'portrait' 
     console.log('Function triggered - ' + orientation) 
     return (w > h) ? 'landscape' : 'portrait'; 

    }; 

    $scope.$watch($scope.getOrientation, function(newValue, oldValue){ 
     $scope.orientation = newValue; 
     console.log('Watch triggered - ' + newValue); 
    }, true); 

}); 

А вот HTML, который имеет набор условный класс, в зависимости от значения $scope.orientation (вероятно, не относится, но на всякий случай) -

<body <?php body_class(); ?> data-ng-controller="bodyCtrl"> 

    <div id="orientationMask" data-ng-class="{visible: orientation != 'landscape'}"> 
     <p>Please turn your device to the <b>landscape</b> orientation.</p> 
    </div> 

    { Additional code, obscured by the mask if it is show... } 

</body> 

ответ

2

При звонке getOrientation из resize событие только выполняет код getOrientation, но он не является интимным угловым, что-то изменилось. Поэтому вам нужно позвонить $apply() по номеру $scope, чтобы указать угловое значение, чтобы запустить цикл дайджеста. После вызова углового цикла дайджеста будет оценен все $watcher и функция наблюдателя будет оценена.

На самом деле это похоже на вызов getOrientation вызова из resize. Событие ничего не делает, связанное с привязкой к области видимости. Таким образом, вы можете удалить этот метод getOrientation оттуда, поскольку он, похоже, вызывает код, который ничего не делает.

Код

angular.element($window).bind('resize', function(){ 
    console.log('Event triggered'); 
    $scope.getOrientation(); //you could remove this method, as its not modifying any scope 
    //will run digest cycle, and the watcher expression will get evaluated 
    $scope.$apply(); //you could also use $timeout(function(){}) here run safe digest cycle. 
}); 
+0

Бинго, благодарю вас за быстрый ответ. Я буду отмечать ваш ответ как можно скорее, как только мне позволено. –

+0

@DavidGard Рад помочь вам .. Посмотрите на редактирование в моем ответе .., который очистит вашу концепцию относительно наблюдателей .. Спасибо :) –

1

Почему вы не просто слушать событие orientationchange, как это?

window.addEventListener("orientationchange", function() { 
      switch(window.orientation){ 
      case -90: 
      case 90: 
       $rootScope.orientation = "landscape"; 
       break; 
      default: 
       $rootScope.orientation = "portrait"; 
      break; 
      }; 

    }, false); 
+1

Я посмотрю на это событие, но мне не очень нравится идея имея доступ к '$ rootScope', если мне это не нужно. –

+0

Вам не обязательно. Вы также можете манипулировать '$ scope.orientation' или что угодно, как только событие срабатывает. –

+0

Fair play Я добавлю его в свой список. –