如何使用 $compile 服务通过 AngularJS 指令包含 HTML 数据
How to use the $compile service to include HTML data with AngularJS directives
我有一个控制器,它使用 ng-repeat 将内容填充到内容区域。问题是其中一些内容需要放在模板文件前面,因此需要编译 'on the fly'。现在我有这个功能动态添加内容:
$scope.layouts = [
{ id: 'Dashboard', icon: 'dashboard', view: '/qph/views/Dashboard.php' },
{ id: 'Customers', icon: 'people', view: '/qph/views/users.php' },
{ id: 'Quotes', icon: 'format_list_bulleted', view: '/qph/views/Quotes.php' }
];
$scope.workspace = {};
var getTemplate = function(id){
var view = 'test.php';
$timeout(function() { //added timeout
if($templateCache.get(view) === undefined) {
$templateRequest(view).then(function (data) {
$scope.workspaces.forEach(function (v) {
if (v.id == id) v.content = $compile(data)($scope);
});
});
} else {
$scope.workspaces.forEach(function (v) {
if (v.id == id) v.content = $compile($templateCache.get(view))($scope);
});
}
}, 2000);
};
$scope.workspaces =
[
{ id: 1, name: "Dashboard", icon: 'dashboard', active:true }
];
getTemplate(1);
我已检查数据变量是否具有预期的 html 内容,但编译输出以下内容:
{"0":{"jQuery331075208394539601512":{"$scope":"$SCOPE","$ngControllerController":{}}},"length":1}
有谁知道为什么它没有按预期编译 html 内容?
模板内容供参考:
<div class="col-sm-6 col-sm-offset-3" ng-controller="UserController">
<div class="col-sm-6 col-sm-offset-3">
<div class="well">
<h3>Users</h3>
<button class="btn btn-primary" style="margin-bottom: 10px" ng-click="user.getUsers()">Get Users!</button>
<ul class="list-group" ng-if="user.users">
<li class="list-group-item" ng-repeat="user in user.users">
<h4>{{user.name}}</h4>
<h5>{{user.email}}</h5>
</li>
</ul>
<div class="alert alert-danger" ng-if="user.error">
<strong>There was an error: </strong> {{user.error.error}}
<br>Please go back and login again
</div>
</div>
</div>
</div>
这里是显示编译内容的标签视图:
<ul class="nav nav-tabs workspace-tabs">
<li class="nav-item" ng-repeat="space in workspaces">
<a class="nav-link" data-toggle="tab" href="#workspace{{space.id}}" ng-class="(space.active == true ) ? 'active show': ''">
<span class="hidden-sm-up"><i class="material-icons md-24">{{space.icon}}</i></span>
<span class="hidden-xs-down">{{space.name}}</span>
<button ng-click="workspace.remove($index)">x</button>
</a>
</li>
</ul>
<div class="tab-content workspace-content">
<div ng-repeat="space in workspaces" id="workspace{{space.id}}" class="tab-pane fade in" ng-class="(space.active == true ) ? 'active show': ''">
{{space.content}}
</div>
</div>
使用指令。
app.directive('myCustomer', function() {
return {
templateUrl: 'test.php',
controller: 'UserController'
};
})
模板缓存将自动管理。
$compile service creates a jqLite object that needs to be added to the DOM with a jqLite or jQuery append() 方法。使用插值 {{ }}
只会呈现 jqLite
对象的字符串化值。
<div class="tab-content workspace-content">
<div ng-repeat="space in workspaces" id="workspace{{space.id}}" class="tab-pane fade in" ng-class="(space.active == true ) ? 'active show': ''">
̶{̶{̶s̶p̶a̶c̶e̶.̶c̶o̶n̶t̶e̶n̶t̶}̶}̶
<compile html="space.html"></compile>
</div>
</div>
相反,使用 custom directive 编译 HTML 数据并将其附加到 DOM:
app.directive("compile", function($compile) {
return {
link: postLink,
};
function postLink(scope, elem, attrs) {
var rawHTML = scope.$eval(attrs.html)
var linkFn = $compile(rawHTML);
var $html = linkFn(scope);
elem.append($html);
}
})
有关详细信息,请参阅 AngularJS Developer Guide - HTML Compiler。
我有一个控制器,它使用 ng-repeat 将内容填充到内容区域。问题是其中一些内容需要放在模板文件前面,因此需要编译 'on the fly'。现在我有这个功能动态添加内容:
$scope.layouts = [
{ id: 'Dashboard', icon: 'dashboard', view: '/qph/views/Dashboard.php' },
{ id: 'Customers', icon: 'people', view: '/qph/views/users.php' },
{ id: 'Quotes', icon: 'format_list_bulleted', view: '/qph/views/Quotes.php' }
];
$scope.workspace = {};
var getTemplate = function(id){
var view = 'test.php';
$timeout(function() { //added timeout
if($templateCache.get(view) === undefined) {
$templateRequest(view).then(function (data) {
$scope.workspaces.forEach(function (v) {
if (v.id == id) v.content = $compile(data)($scope);
});
});
} else {
$scope.workspaces.forEach(function (v) {
if (v.id == id) v.content = $compile($templateCache.get(view))($scope);
});
}
}, 2000);
};
$scope.workspaces =
[
{ id: 1, name: "Dashboard", icon: 'dashboard', active:true }
];
getTemplate(1);
我已检查数据变量是否具有预期的 html 内容,但编译输出以下内容:
{"0":{"jQuery331075208394539601512":{"$scope":"$SCOPE","$ngControllerController":{}}},"length":1}
有谁知道为什么它没有按预期编译 html 内容?
模板内容供参考:
<div class="col-sm-6 col-sm-offset-3" ng-controller="UserController">
<div class="col-sm-6 col-sm-offset-3">
<div class="well">
<h3>Users</h3>
<button class="btn btn-primary" style="margin-bottom: 10px" ng-click="user.getUsers()">Get Users!</button>
<ul class="list-group" ng-if="user.users">
<li class="list-group-item" ng-repeat="user in user.users">
<h4>{{user.name}}</h4>
<h5>{{user.email}}</h5>
</li>
</ul>
<div class="alert alert-danger" ng-if="user.error">
<strong>There was an error: </strong> {{user.error.error}}
<br>Please go back and login again
</div>
</div>
</div>
</div>
这里是显示编译内容的标签视图:
<ul class="nav nav-tabs workspace-tabs">
<li class="nav-item" ng-repeat="space in workspaces">
<a class="nav-link" data-toggle="tab" href="#workspace{{space.id}}" ng-class="(space.active == true ) ? 'active show': ''">
<span class="hidden-sm-up"><i class="material-icons md-24">{{space.icon}}</i></span>
<span class="hidden-xs-down">{{space.name}}</span>
<button ng-click="workspace.remove($index)">x</button>
</a>
</li>
</ul>
<div class="tab-content workspace-content">
<div ng-repeat="space in workspaces" id="workspace{{space.id}}" class="tab-pane fade in" ng-class="(space.active == true ) ? 'active show': ''">
{{space.content}}
</div>
</div>
使用指令。
app.directive('myCustomer', function() {
return {
templateUrl: 'test.php',
controller: 'UserController'
};
})
模板缓存将自动管理。
$compile service creates a jqLite object that needs to be added to the DOM with a jqLite or jQuery append() 方法。使用插值 {{ }}
只会呈现 jqLite
对象的字符串化值。
<div class="tab-content workspace-content">
<div ng-repeat="space in workspaces" id="workspace{{space.id}}" class="tab-pane fade in" ng-class="(space.active == true ) ? 'active show': ''">
̶{̶{̶s̶p̶a̶c̶e̶.̶c̶o̶n̶t̶e̶n̶t̶}̶}̶
<compile html="space.html"></compile>
</div>
</div>
相反,使用 custom directive 编译 HTML 数据并将其附加到 DOM:
app.directive("compile", function($compile) {
return {
link: postLink,
};
function postLink(scope, elem, attrs) {
var rawHTML = scope.$eval(attrs.html)
var linkFn = $compile(rawHTML);
var $html = linkFn(scope);
elem.append($html);
}
})
有关详细信息,请参阅 AngularJS Developer Guide - HTML Compiler。