Octtavius
Octtavius

Reputation: 591

Why directive is not working after page change? Angular

I have a simple youtube directive on one page and works fine. However, if i go to page 2 and then come back, the player doesn't show up any more. Am I missing something here, or I simply misunderstand how directives work ???

Here is the PLUNKER

Directive

app.directive('youtube', function($window) {
  return {
    restrict: "E",

    template: '<div></div>',

    link: function(scope, element, attrs) {
      var tag = document.createElement('script');
      tag.src = "https://www.youtube.com/iframe_api";
      var firstScriptTag = document.getElementsByTagName('script')[0];
      firstScriptTag.parentNode.insertBefore(tag, firstScriptTag);

      var player;

      $window.onYouTubeIframeAPIReady = function() {
        player = new YT.Player(element.children()[0], {
          height: '390',
          width: '640',
          videoId: 'M7lc1UVf-VE'
        });
      };
    },  
  }
});

Controllers and app routes

app.config(['$locationProvider', '$routeProvider', 

function($locationProvider, $routeProvider) {

  $routeProvider.when('/view1', {
    templateUrl: 'page1.html',
    controller: 'firstCtrl'
  });

  $routeProvider.when('/view2', {
    templateUrl: 'page2.html',
    controller: 'secondCtrl'
  });
      $routeProvider.otherwise({redirectTo: '/view2'});
    }])

app.controller('mainCtrl', function($scope) {
  $scope.title = "Main Page"
})

app.controller('firstCtrl', function($scope) {
  $scope.title = "Page 1"
})

app.controller('secondCtrl', function($scope) {
  $scope.title = "Page 2"
})

Thanks!

Upvotes: 1

Views: 209

Answers (1)

Daniel Beck
Daniel Beck

Reputation: 21475

You're injecting the youtube scripts into the page each time the youtube directive is instantiated, and then depending on the onYouTubeIframeAPIReady event to instantiate the player.

This means that the second time the directive is instantiated, onYouTubeIframeAPIReady never fires (because the API was already in place from the first time.)

One way to avoid this is to have the youtube directive's link function check to see whether the youtube API was already injected, and reuse it if so:

  if (window.YT) {
    player = new YT.Player(element.children()[0], {
      height: '390',
      width: '640',
      videoId: 'M7lc1UVf-VE'
    });     
  } else {
    // your existing code here
  }

https://plnkr.co/edit/2gjSd7np8uKVi4YmreiU

(Alternatively, you can embed the youtube API directly as a normal <script> tag in your index.html instead of injecting it via javascript as part of a directive, so it will be ready for any directive that needs to use it).

Upvotes: 2

Related Questions