Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Angular.js createElement is not creating element

Tags:

angularjs

I'm doing a simple tutorial and cannot get past a very simple thing.

I want to create an element on page load. I've followed the code exactly. I'm using Google Chrome. What is wrong with the following that will not create the audio element?:

index.html

<!doctype html>
<html ng-app="myApp">
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
    <script src="js/main.js"></script>
  </head>
  <body>

    <div ng-controller="PlayerController">
        <button ng-click="play()" class="button" ng-show="!playing">Play</button>
        <button ng-click="stop()" class="button alert" ng-show="playing">Stop</button>
        Playing audio: <b>{{ playing }}</b>
    </div>

  </body>
</html>

main.js (in the referenced location js/main.js)

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

app.controller('PlayerController', ['$scope', function($scope) {
  $scope.playing = false;
  $scope.div = document.createElement("div");
  $scope.audio = document.createElement('audio');
  $scope.audio.src = 'media/sample_mpeg4.mp4';
}]);

This is what the source looks like upon page inspection:

<!doctype html>
<html ng-app="myApp">
  <head>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.0.7/angular.min.js"></script>
    <script src="js/main.js"></script>
  </head>
  <body>

    <div ng-controller="PlayerController">
        <button ng-click="play()" class="button" ng-show="!playing">Play</button>
        <button ng-click="stop()" class="button alert" ng-show="playing">Stop</button>
        Playing audio: <b>{{ playing }}</b>
    </div>

  </body>
</html>

As you can see the audio element is not created. I tried this with even simpler examples where I tried to just add a div.

Thanks

like image 596
Joe Essey Avatar asked Dec 25 '22 07:12

Joe Essey


1 Answers

Few things:

  • If you want to manipulate the DOM, it is best to use a directive
  • angular.element(...) creates elements for you (using jQlite), you don't need to use the createElement function directly.
  • When you create an element, you need to add it to the DOM otherwise it won't appear
  • You can inject $element in your controller, but this is not the best pattern to follow

Instead, you can explore this way:

<div player-directive="media/sample_mpeg4.mp4"></div>

And create a directive

app.directive('playerDirective', function() {
    return {
        restrict: 'A',
        template: '<button ng-click="play()" class="button" ng-show="!playing">Play</button><button ng-click="stop()" class="button alert" ng-show="playing">Stop</button>Playing audio: <b>{{ playing }}</b>',
        link: function (scope, element, attrs) {
             var audioSrc = attrs.playerDirective,
                 div = angular.element('<div/>'),
                 audio = angular.element('<audio/>')
                     .attr('src', audioSrc);

              element.append(div.append(audio));

              scope.isPlaying = false;

              scope.play = function () {};

              scope.stop = function () {};
        }
    };
}]);

In this example, we would actually benefit of having the and element in the template with and scope.audioSrc = attrs.playerDirective in the link function.

like image 78
Thomas Roch Avatar answered Jan 11 '23 17:01

Thomas Roch