所以这里存在几个问题,一个是代码,另一个(在我看来)是 Angular 团队实现 Require 功能的不正确方式,我们需要解决这个问题。
为了使您的代码正常工作,您需要在链接函数中引用所需的控制器,直到您这样做,它才会检查控制器是否存在于前面的元素中并且不会抛出异常,另一个问题是您需要在指令中构建所需的控制器才能使链接 api 工作。
不幸的是,角度团队已经创建了默认行为,我不同意,在指令的编译/渲染阶段,当它确定需要什么时,它仍然会渲染有错误的指令的嵌入/模板.因此,即使应用程序抛出异常,它看起来也能正常工作。为了解决这个问题,一旦成功加载,您可以将子指令的链接函数中的作用域属性设置为 true,您将在模板中的 ng-show 中使用该属性。如果由于不满足所需的控制器而导致链接无法运行,则不会显示模板。
这是一个工作示例:
<body>
<div main>
</div>
<script type="text/ng-template" id="main.html">
<span>Hello, {{name}}!</span>
<button ng-click="mainCtrl.log('Log Log Log, wondeful LOG!!!')">LOG</button>
<sub></sub>
</script>
<script type="text/ng-template" id="sub.html">
<div ng-show="loaded">{{name}} this should not work</div><div ng-transclude></div>
</script>
</body>
使用相应的javascript,只需将所需的控制器更改为假名即可在控制台中查看错误:
var app = angular.module('myApp', []);
app.directive('main', function() {
return {
restrict: 'A',
transclude: true,
controllerAs: 'mainCtrl',
controller: function($scope) {
$scope.name = 'World';
this.log = function(test) {
console.log(test);
};
},
templateUrl: 'main.html'
}
});
app.directive('sub', function() {
return {
require: '^main',
restrict: 'E',
transclude: true,
templateUrl: 'sub.html',
link: function(scope, element, attrs, requiredCtrl) {
requiredCtrl.log("heck ya!")
scope.loaded = true;
}
};
});