Às vezes, os serviços da web e APIs retornam conjuntos de dados diferentes para o mesmo tipo de objeto. Por exemplo, a API tumblr retornará uma lista de postagens, mas cada tipo de postagem possui dados diferentes associados a ele: postagens de texto têm título e corpo, enquanto postagens de fotos têm legendas e imagens.
Já que ter diferentes componentes e diretivas para cada tipo de postagem não faz muito sentido (especialmente quando eles são todos exibidos em um fluxo, como no tumblr), é benéfico poder carregar condicionalmente um modelo com base no tipo de postagem de cada postagem individual.
Este código é baseado nestes dois artigos / postagens:
https://github.com/angular/angular.js/issues/1039#issuecomment-10673465
http://onehungrymind.com/angularjs-dynamic-templates/
e aqui está a API do tumblr para referência: http://www.tumblr.com/docs/en/api/v2
components.js
angular.module('components', []).
directive('tumblrPost', ['$compile', '$http', '$templateCache', function($compile, $http, $templateCache) {
var getTemplate = function(contentType) {
var templateLoader,
baseUrl = '/templates/components/tumblr/',
templateMap = {
text: 'text.html',
photo: 'photo.html',
video: 'video.html',
quote: 'quote.html',
link: 'link.html',
chat: 'chat.html',
audio: 'audio.html',
answer: 'answer.html'
};
var templateUrl = baseUrl + templateMap[contentType];
templateLoader = $http.get(templateUrl, {cache: $templateCache});
return templateLoader;
}
var linker = function(scope, element, attrs) {
var loader = getTemplate(scope.post.type);
var promise = loader.success(function(html) {
element.html(html);
}).then(function (response) {
element.replaceWith($compile(element.html())(scope));
});
}
return {
restrict: 'E',
scope: {
post:'='
},
link: linker
};
}]);
news.html (visualização de todas as postagens)
<h1 class="road">News</h1>
<ul id="news">
<li ng-repeat="tumblrPost in posts">
<tumblr-post post="tumblrPost"></tumblr-post>
</li>
</ul>
<p class="read-more"><a href="http://{{posts[0].blog_name}}.tumblr.com/" target="_blank">Read more news</a></p>
text.html (componente de postagem de texto tumblr)
<a href="{{post.post_url}}" target="_blank" class="post-date">{{post.date}}</a>
<h3>{{post.title}}</h3>
<div ng-bind-html="post.body"></div>
<hr>
video.html (componente de postagem de vídeo tumblr, para comparação)
<a href="{{post.post_url}}" target="_blank" class="post-date">{{post.date}}</a>
<div ng-bind-html-unsafe="post.player[0].embed_code" ui-jq="fitVids"></div>
<div ng-bind-html="post.caption"></div>
<hr>