从动态插入的标签编译指令
Compile directive from dynamically inserted tag
我想创建一个由几个较小的 "apps" 组成的仪表板。我有以下标记(简化):
<div id="rowcontainer">
<div ng-repeat="appRow in dashboard.appRows">
<div class="row">
<div ng-repeat="app in appRow.apps">
{{app}}
</div>
</div>
</div>
</div>
dashboard.appRows
保留由我的 "apps" (appRow.apps
) 组成的行。
当我单击一个按钮时,我想动态添加一个指令,方法是将 {{app}}
占位符替换为指令标记,然后编译 ($compile
) 我刚刚插入的这个标记。
问题是,在点击处理程序中,当我更新我的模型时,函数中的 DOM 没有更新(显然)并且 $()
将无法找到 DOM 节点。
澄清一下:
我想做这个:
<div ng-repeat="app in appRow.apps">
{{app}}
</div>
变成这样:
<div ng-repeat="app in appRow.apps">
<my-directive></my-directive>
</div>
最后 $compile
以上为:
<div ng-repeat="app in appRow.apps">
<my-directive>CONTENTS OF MY TEMPLATE</my-directive>
</div>
在同一个函数中尝试这一切是行不通的,调用$scope.$apply()
会抛出错误($digest
已经运行)而且我不知道是否有回调。并且查找 DOM 元素不起作用。感谢您的帮助或替代建议。
进一步说明:
指令 <my-directive>
可以是任何指令(<my-directive>
、<your-directive>
、...)。在我的模板中有一个占位符 {{app}}
,我将在运行时将其替换为提到的任何指令(假设您单击一个按钮并且该指令正在替换 {{app}}
)。然后我希望我的指令起作用。
我能想到的一种方法是使用容器指令来保存编译后的指令。
angular.module('test', [])
.controller('Test', TestController)
.directive('appLoader', appLoaderDirective)
.directive('apple', appleDirective)
.directive('banana', bananaDirective);
function TestController($scope) {
$scope.apps = ['apple', 'banana']
}
function appLoaderDirective($compile) {
return {
scope: { app: '=' },
link: function(scope, element, attr) {
// you might have to do camel case to kebab case conversion here, depending on your input
element.append($compile("<" + scope.app + "></" + scope.app + '>')(scope));
}
}
}
function appleDirective() {
return {
template: '<div>i am apple!</div>'
}
}
function bananaDirective() {
return {
template: '<div>i am banana!</div>'
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<div ng-app='test' ng-controller='Test'>
<div ng-repeat='app in apps'>
<app-loader app='app'></app-loader>
</div>
</div>
我想创建一个由几个较小的 "apps" 组成的仪表板。我有以下标记(简化):
<div id="rowcontainer">
<div ng-repeat="appRow in dashboard.appRows">
<div class="row">
<div ng-repeat="app in appRow.apps">
{{app}}
</div>
</div>
</div>
</div>
dashboard.appRows
保留由我的 "apps" (appRow.apps
) 组成的行。
当我单击一个按钮时,我想动态添加一个指令,方法是将 {{app}}
占位符替换为指令标记,然后编译 ($compile
) 我刚刚插入的这个标记。
问题是,在点击处理程序中,当我更新我的模型时,函数中的 DOM 没有更新(显然)并且 $()
将无法找到 DOM 节点。
澄清一下:
我想做这个:
<div ng-repeat="app in appRow.apps">
{{app}}
</div>
变成这样:
<div ng-repeat="app in appRow.apps">
<my-directive></my-directive>
</div>
最后 $compile
以上为:
<div ng-repeat="app in appRow.apps">
<my-directive>CONTENTS OF MY TEMPLATE</my-directive>
</div>
在同一个函数中尝试这一切是行不通的,调用$scope.$apply()
会抛出错误($digest
已经运行)而且我不知道是否有回调。并且查找 DOM 元素不起作用。感谢您的帮助或替代建议。
进一步说明:
指令 <my-directive>
可以是任何指令(<my-directive>
、<your-directive>
、...)。在我的模板中有一个占位符 {{app}}
,我将在运行时将其替换为提到的任何指令(假设您单击一个按钮并且该指令正在替换 {{app}}
)。然后我希望我的指令起作用。
我能想到的一种方法是使用容器指令来保存编译后的指令。
angular.module('test', [])
.controller('Test', TestController)
.directive('appLoader', appLoaderDirective)
.directive('apple', appleDirective)
.directive('banana', bananaDirective);
function TestController($scope) {
$scope.apps = ['apple', 'banana']
}
function appLoaderDirective($compile) {
return {
scope: { app: '=' },
link: function(scope, element, attr) {
// you might have to do camel case to kebab case conversion here, depending on your input
element.append($compile("<" + scope.app + "></" + scope.app + '>')(scope));
}
}
}
function appleDirective() {
return {
template: '<div>i am apple!</div>'
}
}
function bananaDirective() {
return {
template: '<div>i am banana!</div>'
}
}
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.8/angular.min.js"></script>
<div ng-app='test' ng-controller='Test'>
<div ng-repeat='app in apps'>
<app-loader app='app'></app-loader>
</div>
</div>