[英]Parse content within AngularJS directive before rendering template
我在頁面上有一個由服務器呈現的元素。 我們稱之為播放列表 。 這將是一個指令。
<div playlist></div>
播放列表在Angular編譯時間之前包含許多曲目 。
<div class="Track" data-track-name="Pompeii" data-*="etc">...</div>
加載頁面后,我將包括AngularJS並解析播放列表和指令。
當我初始化播放列表指令時,我想在編譯它的模板之前循環遍歷它的內容,並使用收集的數據在屬於播放列表指令的ng-repeat
指令中繪制軌道指令。
問題:
在模板替換指令標記內的任何內容之前,是否存在用於解析內容的本機功能? 一旦我進入指令控制器,內容就已經被替換了。
我的問題有更好的解決方案嗎? 遺憾的是,我不得不使用已在頁面上呈現的內容作為數據源,作為該項目的大量需求的解決方案
我可以在服務器的內容中使用track指令來避免DOM操作嗎?
額外的解釋
在編譯之前:
<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 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>
假設這是您的數據結構,您可以在沒有指令的情況下輕松完成所有操作:
數據結構/控制器
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並將其放入控制器范圍數組中。 然后,您可以將此范圍傳遞到模板或模板URL中。 使用你需要的任何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 = [];
}
}
});
[編輯#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 = [];
}
}
});
我找到了一個使用ngTransclude非常滿意的解決方案。
我從服務器上以指令形式為軌道編寫我的內容:
<div track track-id="245" track-name="Pompeii" track-duration="3.24">Pompeii</div>
在我的播放列表模板中,我使用了一個<div ng-transclude></div>
指令,該指令從原始DOM中獲取播放列表的內容,將其解析為單獨的指令並注入到播放列表模板的指定部分。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.