Ce que je sais, c'est quand je veux insérer du HTML dans la vue, j'utilise 'ng-bind-html'
ou 'ng-bind-html-unsafe'
.
Ce que je ne sais pas, c'est comment insérer du HTML et faire Angular analyser son contenu
c'est-à-dire s'il y a 'ng-repeat'
, Je veux Angular pour l'analyser?
exemple:
HTML:
<div ng-repeat="t in ts" ng-bind-html-unsafe="t.html()"></div>
JS:
function Controller($scope) {
$scope.ts = {obj1: new obj(), obj2: new obj(), ob3: new obj()};
}
function obj() {
// which may be "<div ng-repeat="s in somthing">{{s}}</div>"
// or "<ul><li ng-repeat="s in somthing">{{s.k}}</li></ul>"
// or something else
var _html;
this.html = function() {
return _html;
}
}
J'ai essayé d'utiliser ce qui précède, mais Angular juste imprimer {{s}}
ou {{s.k}}
tel quel.
Vous pouvez compiler du code HTML arbitraire dans une vue angular avec le $compile
service ( docs ).
app.run(function($rootScope, $compile, $rootElement) {
// We'll create a new scope to use as the context for the view.
$scope = $rootScope.$new();
$scope.model = [{name: 'first'}, {name: 'second'}, {name: 'third'}];
// Calling `$compile(html)` returns a function that, when called with
// a context object, links the compiled HTML to the given context (e.g.
// binds scope-based expressions in the view to the passed in scope).
var html = "<div ng-repeat='m in model'>{{m.name}}</div>";
var linkingFunction = $compile(html);
var elem = linkingFunction($scope);
// You can then use the DOM element like normal.
$rootElement.append(elem);
});
Dans ce cas, j'ai attaché la vue au $rootElement
(qui est l'élément qui a été utilisé lors du démarrage du module, généralement par le ng-app
directive); dans de nombreux cas, vous ferez ce genre de chose dans la fonction de liaison d'une directive et aurez accès à l'élément en question. Vous pouvez, bien sûr, obtenir le HTML brut à l'aide de jQuery ou jqLite, mais n'oubliez pas d'autoriser au moins un cycle de résumé sur la portée liée avant de le faire (sinon le HTML n'aura pas encore été mis à jour avec les valeurs de la portée) .
Exemple de travail: http://jsfiddle.net/BinaryMuse/QHhVR/
Dans les entrailles du ng-include
directive, Angular fait exactement cela :
$compile(currentElement.contents())(currentScope);
[Mise à jour]
Voici un exemple plus complet qui démontre quelque chose d'un peu plus près de votre question mise à jour:
app.controller("MainController", function($scope) {
$scope.ts = [
{
elements: ['one', 'two', 'three'],
html: '<div ng-repeat="elem in t.elements">{{elem}}</div>'
},
{
things: [8, 9, 10],
add: function(target) {
var last = target[target.length - 1];
target.Push(last + 1);
},
html: '<ul><li ng-repeat="num in t.things">{{num}}</li>' +
'<li><button ng-click="t.add(t.things)">More</button></li></ul>'
}
];
});
app.directive("bindCompiledHtml", function($compile, $timeout) {
return {
template: '<div></div>',
scope: {
rawHtml: '=bindCompiledHtml'
},
link: function(scope, elem, attrs) {
scope.$watch('rawHtml', function(value) {
if (!value) return;
// we want to use the scope OUTSIDE of this directive
// (which itself is an isolate scope).
var newElem = $compile(value)(scope.$parent);
elem.contents().remove();
elem.append(newElem);
});
}
};
});
<div ng-controller="MainController">
<div ng-repeat="t in ts" bind-compiled-html="t.html"></div>
</div>
Exemple de travail: http://jsfiddle.net/BinaryMuse/VUYCG/
Cela ne vaut rien que les extraits HTML utilisent t.elements
et t.things
car t
est la valeur de portée créée par le ng-repeat
dans le HTML externe. Vous pouvez faire un peu de gymnastique pour rendre cela un peu plus agréable si vous le souhaitez.
Si vous disposez d'un nombre fini d'options pour les éléments de la répétition, vous pouvez utiliser ng-switch à la place ou ng-include si le code HTML provient du serveur.
Quelque chose comme ça?
<div ng-repeat="item in items">
<div ng-bind-html-unsafe="item.html"></div>
</div>
où
items = [
{
html: 'test<br/>test'
},
{
html: 'test2<br/>test2'
}
]