Измените templateUrl "больше, чем один" с помощью директив в AngularJS

Я искал способ изменить templateUrl как событие изменения размера. Я нашел ответ в ссылке:

Измените templateUrl директивы в зависимости от разрешения экрана AngularJS

Написал г-н. "Dfsq". Это работало хорошо до тех пор, пока мне не нужно было выполнить один и тот же процесс в двух разных шаблонах одновременно. Не работал. Когда я удаляю директиву, другая начинает работать.

Любая идея, где я не прав.

Плункер следует. Пример плунжера здесь!

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';
});

angular.module('plunker')
  .directive('browseContent', function($window) {
    return {
        restrict: 'E',
        template: '<div ng-include="templateUrl"></div>',
        link: function(scope) {
            
            $window.onresize = function() {
                changeTemplate();
                scope.$apply();
            };
            changeTemplate();
            
            function changeTemplate() {
                var screenWidth = $window.innerWidth;
                if (screenWidth < 768) {
                    scope.templateUrl = 'browse-content-mobile.html';
                } else if (screenWidth >= 768) {
                    scope.templateUrl = 'browse-content.html';
                }
            }
        }
    }
})
  .directive('segundoContent', function($window) {
    return {
        restrict: 'E',
        template: '<div ng-include="templateUrl2"></div>',
        link: function(scope) {
            
            $window.onresize = function() {
                changeTemplate2();
                scope.$apply();
            };
            changeTemplate2();
            
            function changeTemplate2() {
                var screenWidth = $window.innerWidth;
                if (screenWidth < 768) {
                    scope.templateUrl2 = 'segundoContent.html';
                } else if (screenWidth >= 768) {
                    scope.templateUrl2 = 'segundoContent-mobile.html';
                }
            }
        }
    }
});
<!DOCTYPE html>
<html ng-app="plunker">

<head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>
        document.write('<base href="' + document.location + '" />');
    </script>
    <link rel="stylesheet" href="style.css" />
    <script data-require="angular.js@1.2.x" src="https://code.angularjs.org/1.2.22/angular.js" data-semver="1.2.22"></script>
    <script src="app.js"></script>
</head>

<body ng-controller="MainCtrl">
    <browse-content></browse-content>
    <segundo-content></segundo-content>
</body>

</html>

Я ценю помощь

1 ответ

Решение

В настоящее время вы используете onresize метод, который потенциально регистрирует одно событие при изменении размера окна, поэтому, когда у вас есть 2-я директива в DOM, она регистрирует последнюю функцию при изменении размера.

В идеале вы должны использовать resize с handler functoin, так что несколько событий будут зарегистрированы одновременно.

директива browseContent

var w = angular.element($window);
w.on('resize', function(e) {
    changeTemplate();
    scope.$apply();
});

Директива segundoContent

var w = angular.element($window)
w.on('resize', function() {
    changeTemplate2();
    scope.$apply();
});

Демо Планкр


Более удобным способом было бы просто использовать одну директиву и передать ей саму функцию templateUrl / templateUrl, чтобы директива стала более общей, и вам не нужно было бы создавать две директивы одновременно.

HTML

<body ng-controller="MainCtrl">
    <browse-content templates="htmls"></browse-content>
    <browse-content templates="segundo"></segundo-content>
</body>

Код

app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';
  $scope.htmls = ['browse-content-mobile.html', 'browse-content.html'];
  $scope.segundo = ['segundoContent.html', 'segundoContent-mobile.html'];
});

angular.module('plunker')
  .directive('browseContent', function($window) {
    return {
      restrict: 'E',
      template: '<div ng-include="templateUrl"></div>',
      link: function(scope, element, attrs) {
        var w = angular.element($window);
        w.on('resize', function(e) {
          changeTemplate();
          scope.$apply();
        });
        var templates = scope.$eval(attrs.templates);
        console.log(templates)
        changeTemplate();

        function changeTemplate() {
          var screenWidth = $window.innerWidth;
          if (screenWidth < 768) {
            scope.templateUrl = templates[0];
          } else if (screenWidth >= 768) {
            scope.templateUrl = templates[1];
          }
        }
      }
    }
});

Лучший подход


Другие вопросы по тегам