user3403205 user3403205 - 4 months ago 24
AngularJS Question

Change the templateUrl of "more then one" with directives in AngularJS

I've been looking for a way to change the templateUrl as the resize event.
I found the answer in the link:

Change the templateUrl of directive based on screen resolution AngularJS

Posted by mr. "Dfsq". It worked well until when I needed to do the same process in two different templatesUrls the same time. Did not work.
When I delete a directive the other goes to work.

Any idea where I am wrong.

Plunker follows.
Plunker Example Here!



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>





I appreciate the help

Answer

Currently you are using onresize method which will potentially register a single event on resize of window, so when you are having 2nd directive in DOM it registering latest function on resize.

Ideally you should be using resize with handler functoin, so that multiple event will get register at the same time.

browseContent Directive

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

segundoContent Directive

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

Demo Plunkr


More convenient way would be just use a single directive and pass templateUrl function / templateUrl's itself to it, so that directive will become more generic & you would not need to create a two directive at a time.

HTML

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

Code

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];
          }
        }
      }
    }
});

Better Approach


Comments