是否可以编译此html模板字符串:
"<p>List of products from {{supplier.name}}</p>
<p ng-repeat="ref in refs">{{ref}}</p>"
直接输入一个html字符串,如:
"<p>List of products from Some Supplier</p>
<p>a0120</p>
<p>a0241</p>
<p>z1242</p>
<p>z3412</p>"
或至少不太干净的版本:
"<p class="ng-scope ng-binding">List of product from Duval</p>
<!-- ngRepeat: ref in refs track by $index -->
<p ng-repeat="ref in refs track by $index" class="ng-scope ng-binding">a0120</p>
<p ng-repeat="ref in refs track by $index" class="ng-scope ng-binding">a0241</p>
<p ng-repeat="ref in refs track by $index" class="ng-scope ng-binding">z1242</p>
<p ng-repeat="ref in refs track by $index" class="ng-scope ng-binding">z3412</p>"
我尝试使用$ compile(templateStr)($ scope),但返回的dom元素未完全处理。 但是我没有使用以下指令将其编译为页面元素,并且检查该元素我可以看到它具有我正在寻找的最终html:
app.directive('compile', function($compile) {
return{
restrict: 'A',
scope: {
compile: '=compile',
data: '=ngData'
},
link: function(scope, element, attrs) {
scope.$watch('data',
function(value) {
for (var k in scope.data)
scope[k] = scope.data[k];
}
)
scope.$watch('compile',
function(value) {
element.html(value);
var a = $compile(element.contents())(scope);
}
)
}
}
})
有什么方法可以直接从模板中获取最终的HTML吗? 感谢
PS: 我在这里想要实现的是直接在CKEditor中编辑模板(在文本模式下,而不是源代码) 并且最终只能进入源模式以添加一些“ng-repeat”属性。 使用像Handlebars这样的模板引擎需要在html元素之外的占位符,并且由CKEditor自动删除,因为它只处理html。
可能的解决方案(hacky): 一种可能的方法是在隐藏元素上使用compile指令,并在控制器上加载视图后读取元素的内容:
$scope.$on('$viewContentLoaded', $scope.onLoaded); $timeout(function() { var el =$("#text div")[0] cleanAngularStuff(el) $scope.currMailTemplate.processed = el.innerHTML });
cleanAngularStuff函数只是为了清除额外的角度指令和类。
如果有人想要使用它或改进它,我会发布它here。
在不向页面添加元素的情况下更好的方法吗?
答案 0 :(得分:4)
您需要做的是在$ digest循环后访问已编译的元素。
所以在$ digest周期内你可以这样做:
templateString = '<some-template-code/>';
...
var compiled = $compile(templateString)(scope);
// scope.$digest // only call this if not within a $digest cycle
// you can do a $timeout to let the previous digest cycle complete
$timeout(function(){
var theHtml = compiled[0].outerHTML;
console.log('the html with the variables', theHtml);
});
如果您尚未进入摘要周期,则需要手动调用scope.$digest()
。您可以在下面看到嵌入式示例。
(function(){
"use strict";
var app = angular.module('soApp', []);
app.directive('showCompiledTemplate',[
'$compile','$timeout',
function($compile , $timeout) {
return {
restrict: 'E',
template: '<div class="compiled-template">' +
'<div><textarea cols="40" rows="15" readonly></textarea></div>' +
'<div class="output"></div>' +
'</div>',
scope: {
data: '=',
template: '='
},
link: function(scope,elem,attrs) {
var textarea = elem.find('textarea')[0];
var output = elem.children().children().eq(1);
var updateOutput = function(tpl) {
var compiled = $compile(tpl)(scope);
$timeout(function(){
var theHtml = compiled[0].outerHTML;
textarea.value = theHtml;
output.html(theHtml);
});
};
scope.$watch("template",function(tpl){
updateOutput(tpl);
});
scope.$watch("data",function(){
updateOutput(scope.template);
},true);
}
};
}
]);
app.controller('MainCtrl', function() {
this.data = {
name: 'John',
list: ['one duck','two ducks','three ducks']
};
//this.template = "<div>hi</div>";
var template = '';
template += '<div>\n';
template += ' <p>{{data.name}}</p>\n';
template += ' <ul>\n';
template += ' <li ng-repeat="item in data.list">{{item}}</li>\n';
template += ' </ul>\n';
template += '</div>\n';
this.template = template;
});
})();
.form-field {
padding-bottom: 10px;
}
.form-field span {
width: 70px;
display: inline-block;
}
.compiled-template {
display: -webkit-flex;
display: flex;
-webkit-flex-direction: row;
flex-direction: row;
}
.compiled-template textarea {
background-color: #eee;
margin-right: 10px;
}
.compiled-template .output {
border: 1px solid #ccc;
padding: 10px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.js"></script>
<div ng-app="soApp">
<div ng-controller="MainCtrl as main">
<div class="form-field">
<span class="form-label">Name:</span>
<input type="text" ng-model="main.data.name" /> <br/>
</div>
<div class="form-field">
<span class="form-label">Template:</span>
<textarea ng-model="main.template" cols="40" rows="8"></textarea> <br/>
</div>
<div>
<show-compiled-template data="main.data" template="main.template" />
<div>
</div>
</div>
答案 1 :(得分:0)
可以通过向您的指令提供模板来完成,如下所示。
app.directive('compile', function($compile) {
return{
restrict: 'A',
template: '<p>List of products from {{supplier.name}}</p>
<p ng-repeat="ref in refs">{{ref}}</p>'
scope: {
refs: '='
supplier: '='
},
link: function(scope, element, attrs) {
# Your code goes here
}
}
})