我的父指令带有一个包含有关网站结构信息的文件,并动态构建模板字符串。此字符串的内容引用其他指令。这些可以从源获取数据以构建(例如)表。
因为他们都使用$ http.get来获取数据,所以我想在使用所需控制器准备好这些子指令时通知父指令。
问题:父指令使用$ compile来构建站点,并且不“转发”控制器,导致“错误:[$ compile:ctreq] http://errors.angularjs.org/1.4.1/ $ compile / ctreq ...”< / p>
已经找到了这个答案:“Angular $compile with required controller”这不是一个很大的帮助,特别是因为transcludedControllers似乎已被弃用而且在我的代码中不起作用。
任何帮助或只是指向另一个已经问过/已回答的问题,我们非常感谢。
angular.module('TestDirectives', [])
.directive('widgetBlock', function ($compile) {
return {
restrict: 'A',
replace: true,
controller: function ($scope) {
this.reportReady = function () {
$scope.widgetready = String(Number($scope.widgetready) + 1);
}
},
link: function (scope, elem, attr) {
// template data will be constructed dynamically based on a
// xml - file fetched with $http.get
var template = '<div><p >This isn\'t always fun</p>' +
'<div mini-widget></div>' +
'<div micro-widget></div></div>';
var content = $compile(template)(scope)
elem.append(content);
attr.$observe('widgetready', function (newValue) {
// quantity of widgets depends on widgets found in xml - file
if (newValue === "2") {
// all widgets on screen, translate some keys
console.info("Application is ready to translate!!");
}
});
}
};
})
.directive('miniWidget', function ($compile, $http) {
return {
restrict: 'A',
require: '^widgetBlock',
scope: {},
link: function (scope, elem, attr, ctrl) {
$http.get('json/daten.json').then(function (data) {
scope.person = data.data;
var test = '<p>hello {{person.name}}</p>';
var content = $compile(test)(scope)
elem.append(content);
ctrl.reportReady();
});
}
}
})
.directive('microWidget', function ($compile, $http) {
return {
restrict: 'A',
require: '^widgetBlock',
scope: {},
link: function (scope, elem, attr, ctrl) {
$http.get('json/daten2.json').then(function (data) {
scope.person = data.data;
var test = '<p>Whatever {{person.name}}</p>';
var content = $compile(test)(scope)
elem.append(content);
ctrl.reportReady();
});
}
}
});
要完成,主要应用
angular.module('DirectiveTestApp', ['TestDirectives'])
.controller('MainController', function ($scope) {
$scope.widgetready = "0";
});
和html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Directives Test</title>
</head>
<body ng-app="DirectiveTestApp">
<div ng-controller="MainController">
<div widget-block widgetready="{{widgetready}}">
</div>
</div>
<script src="bower_components/angular/angular.min.js"></script>
<script src="script/app.js"></script>
<script src="script/directives.js"></script>
</body>
</html>
非常感谢!
答案 0 :(得分:0)
当您$compile
然后link
- 您正在使用$compile(template)(scope)
时 - 在链接阶段,microWidget
指令会查找所需的控制器DOM树。问题是你的模板当时不在DOM中。
有两种方法可以解决这个问题:
#1:使用cloneAttachFn
:
链接功能的第二个参数($compile(template)
的结果)允许您指定cloneAttachFn
- 请参阅documentation。此函数在链接阶段之前调用,并获取待链接节点的克隆版本。使用该函数将元素放在需要的位置:
var content = $compile(template)(scope, function cloneAttachFn(clonedContent){
// this happens prior to link-phase of the content
elem.append(clonedContent);
});
// this happens after link-phase of the content, so it doesn't work
// elem.append(content)
(顺便说一下,content[0] === clonedContent[0]
)
#2:追加$compile
/ link
之前的内容(正如this question的回答中所建议的那样):
var content = angular.element(template);
elem.append(content);
$compile(content)(scope);
<强> Demo 强>