Ответ 1
Вы можете скомпилировать произвольный HTML в представление angular с помощью службы $compile
(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);
});
В этом случае я привязал представление к $rootElement
(который является элементом, который использовался при начальной загрузке модуля, обычно с помощью директивы ng-app
); во многих случаях вы будете делать такие вещи в директивной функции связывания и будете иметь доступ к рассматриваемому элементу. Конечно, вы можете получить необработанный HTML с помощью jQuery или jqLite, но не забудьте разрешить хотя бы один цикл дайджеста в связанной области до того, как вы это сделаете (иначе HTML еще не будет обновлен значениями из области).
Рабочий пример: http://jsfiddle.net/BinaryMuse/QHhVR/
В недрах директивы ng-include
Angular выполните эту самую вещь:
$compile(currentElement.contents())(currentScope);
[Обновление]
Вот более полный пример, демонстрирующий нечто более близкое к вашему обновленному вопросу:
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>
Рабочий пример: http://jsfiddle.net/BinaryMuse/VUYCG/
Не стоит ничего, что фрагменты HTML используют t.elements
и t.things
, потому что t
- это значение области, созданное ng-repeat
во внешнем HTML. Вы могли бы сделать какую-то сферу гимнастики, чтобы сделать это немного лучше, если хотите.