具有继承作用域的内部嵌套指令在具有独立作用域的外部指令中使用

Inner nested directive with inherited scope used in outer directive with isolated scope

注意:我正在修改这个问题以提高评分。

我开发了以下具有隔离范围的指令:

app.directive('outerIsolated', function () {
    return {
        restrict: 'A',
        scope: {
            theData:'=',
            ...
        },
        replace: true,
        templateUrl: './photo-list-template.html',
        link: function ($scope, elm, attrs) {
           ...
           ...
           ...
        }
    };
});

此外,我还开发了以下具有继承作用域的内部指令。

app.directive('innerInherited', ['$compile', '$timeout', '$parse', function ($compile, $timeout, $parse) {
    return {
        scope: false;
        link: function (scope, el, attrs, ngModel) {
           ...
           ...
           ...            }
    };
}]);

问题:

如果我使用指令 outerIsolated 作为内部指令 innerInherited 的父指令,那么所有对继承作用域变量的引用都将不起作用。

innerInherited 指令本身工作得很好并且已经被广泛使用。现在,我无法将其更改为隔离范围。该指令实际上称为 check-if-required 并将循环遍历所有子输入字段以找出是否有必填字段,并将其设置为必填字段。

就在几天前,我了解了具有隔离范围的指令,可用于开发可重用的组件。我喜欢这个想法,我开发了一个调用 upload-photo-list,我在这里将其称为 outerIsolated

有没有办法轻松解决这个问题?

一种直接的方法是反转指令的嵌套。因此,我尝试在外部级别使用具有继承范围的指令,但是,现在的问题是外部指令的 link 函数在被模板替换后没有看到内部指令的元素.我什至使用这段代码来尝试等待文档准备好:

angular.element(document).ready(function (){...}

...但是,外部指令仍然无法到达内部指令生成的 HTML 个元素。

感谢您帮助找到解决方案。

谢谢。

老问题:

注:此部分已作废。我把它放在这里只是为了跟踪目的。

我正在使用 ng-signature-pad 和签名板插件构建一个简单示例。

Click here to see the sample HTML file as per the download

我注意到只有将以下脚本标记放在 </body> 标记之前才有效(与上面 link 中提供的示例源代码相同):

  <script src="js/app.js"></script>

如果我将上面的脚本标签放在 <head> 标签中,它不会受到影响。

有人可以向我解释为什么吗?

我需要更详细地查看您所引用的项目,但我认为您所使用的库和 app.js 正在引用页面上的元素。

如果 HEAD 标记中有脚本,则这些元素不存在。通过将它们放在 BODY 元素的底部,您可以确保这些元素确实在浏览器中。

解决我的问题的最快方法如下...

我必须在外层使用具有继承作用域 check-if-required 的指令,在内部层使用具有独立作用域 upload-photo-list 的指令。

但是,我不得不对指令进行两次修改 check-if-required:

  1. 在 link 函数中添加 $timeout 以确保内部指令在循环遍历所有 input 元素之前完成其 HTML 的渲染,如下所示:

代码:

var children;
$timeout(function() {
    children = $(":input", el);
    el.removeAttr('check-if-required');
    angular.forEach(children, function(value, key) {
        ...
        ...
    });
})
  1. 必须根据元素的范围编译元素:

代码:

angular.forEach(children, function(value, key) {
    if(typeof (value.id) != 'undefined') {
        if (scope.isFieldRequired(value.id)) {
        angular.element(value).attr('required', true);
        $compile(value)(angular.element(value).scope());
    }
})

到目前为止,这个解决方案对我来说效果很好。

欢迎任何改进反馈。

塔雷克