Parse the contents in AngularJS directive before the rendering template

I have an element on the page that was provided by the server. Let’s call it a playlist . This will be a directive.
<div playlist></div>

A playlist contains several tracks prior to Angular compilation time.
<div class="Track" data-track-name="Pompeii" data-*="etc">...</div>

After loading the page, I turn on AngularJS and parse the playlist and directive.

When I initialize directive playlist , I would like to pass it before compiling the contents of this template and use the collected data to draw directives track in ng-repeatbelonging to the directive the playlist .

Questions:

  • Is there a built-in function for analyzing content before the template replaces any content in the directive tag? When I am in the controller, the contents have already been replaced.

  • Is there a better solution to my problem? Unfortunately, I have to use the content already presented on the page as a data source as a solution to a number of requirements for this project.

  • Can I use the directive tracks in my content from the server to avoid manipulating the DOM?

Additional explanation

Before compiling:

<div playlist>
   <div class="Track" data-track-name="Pompeii">Pompeii</div>
   <div class="Track" data-track-name="Weight of living">Weight of living</div>
</div>

After compilation:

<div playlist>
   <!-- from playlist template -->
   <div class="Playlist">
       <div class="Playlist-controls">....</div>
       <div class="Playlist-tracks">
           <div track ng-repeat="track in tracks">
               <!-- from track template -->
               <div class="Track">...</div>
            </div>
       </div>

   </div>
</div>
+4
source share
2 answers

I found a solution that I really like with ngTransclude .

:

<div track track-id="245" track-name="Pompeii" track-duration="3.24">Pompeii</div>

playlist <div ng-transclude></div>, DOM, .

0

, , :

/

function ctrl($scope) {
$scope.Playlists = [
  { name: 'Playlist 1', tracks: [ 'Track 1', 'Track 2', ..., 'Track n'] },
  { name: 'Playlist 2', tracks: [ 'Track 1', 'Track 2', ..., 'Track n'] },
  ...
  { name: 'Playlist n', tracks: [ 'Track 1', 'Track 2', ..., 'Track n'] }
];
}

:

<div ng-controller="ctrl">
  <div ng-repeat="playlist in Playlists">
    <div> {{ playlist.name }} </div>
    <div ng-repeat="track in playlist.tracks">
       {{ track }}
    </div>
  </div>
</div>

[]

DOM, . DOM . . jQuery, DOM. jsFiddle

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

myApp.directive('playlist', function() {
    return {
        restrict: 'A',
        scope: false,
        link: {
            pre: function(scope, element) {
                $('.Track').each(function(index, ele) {
                   scope.tracks.push($(ele).attr('data-track-name')); 
                });
                console.log(scope.tracks);
            },
            post: function(scope, element) {
              // do any compiling, etc...    
            }
        },
        controller: function($scope, $element) {
            $scope.tracks = [];
        }
    }
});

[edit # 2] . , - . jsFiddle

:

<div ng-app="myApp">
    <script type="text/ng-template" id="tpl.html">
        <div>My playlist controls</div>
        <div ng-repeat="track in tracks">
           {{ track }}
        </div>
   </script>
    <div playlist>
       <div class="Track" data-track-name="Pompeii">Pompeii</div>
       <div class="Track" data-track-name="Weight of living">Weight of living</div>
    </div>
</div>

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

myApp.directive('playlist', function($compile, $templateCache) {
    var extractData = function(scope) {
        $('.Track').each(function(index, ele) {
            scope.tracks.push($(ele).attr('data-track-name'));
        });
    }

    return {
        replace: true,
        restrict: 'A',
        compile: function(ele, attr, ctrl) {
            return {
              pre: function preLink(scope, ele, attr, ctrl) {
                  extractData(scope);
              },
              post: function postLink(scope, ele, attr, ctrl) {
                  ele.html($templateCache.get("tpl.html"));
                  $compile(ele.contents())(scope);
              }
            }
        },
        controller: function($scope, $element) {
            $scope.tracks = [];
        }
    }
});
+3

Source: https://habr.com/ru/post/1533721/


All Articles