在transclude内容中找不到指令所需的Angularjs控制器

在transclude内容中找不到指令所需的Angularjs控制器,angularjs,directive,Angularjs,Directive,最近我用angular开发了一个指令,有一个指令像ng repeat生成一些记录,我用transclude来实现它。但它引发了一个错误,即“找不到指令‘bSpan’所需的控制器‘aArea!” 1。模块A代码 var moduleA = angular.module("moduleA", []); moduleA.directive("aArea", function () { return { restrict: 'E',

最近我用angular开发了一个指令,有一个指令像ng repeat生成一些记录,我用transclude来实现它。但它引发了一个错误,即“找不到指令‘bSpan’所需的控制器‘aArea!”

1。模块A代码

    var moduleA = angular.module("moduleA", []);

    moduleA.directive("aArea", function () {
        return {
            restrict: 'E',
            transclude:'element',
            scope: {
                amount:"="
            },
            template: '<div id=\"cc\" ng-transclude></div>',
            controller: function ($scope,$element,$attrs) {
                this.getData = function (data) {
                    return data + " is ok";
                }
            },
            compile: function (tElement, attrs, linker) {
                var parentElement = tElement.parent();

                return {
                    pre: function () {

                    },
                    post: function (scope) {
                        linker(scope.$parent,function (clone,scope) {
                            parentElement.append(clone);
                        });
                        linker(scope.$parent, function (clone, scope) {
                            parentElement.append(clone);
                        });
                        linker(scope.$parent, function (clone, scope) {
                            parentElement.append(clone);
                        });
                    }
                }
            }
        }
    });

   moduleA.directive("bSpan", function () {
        return {
            restrict: 'E',
            scope: {
                data: "=",
            },
            template: '<span style=\"background-color:gray;color:orange\">{{data}}</span>',
            require: "^aArea",
            link: function ($scope, $element, $attrs, controller) {
                var data = "abc";
            }
        }
    });
    var moduleB = angular.module("moduleB", []);

    moduleB.directive("myItem", function () {
        return {
            restrict: 'E',
            scope: {
                item: "=",
                itemTemplate: '='
            },
            priority: 1000,
            terminal:false,
            template: '<ng-include src=\"itemTemplate\"/>',
            controller: function ($scope, $element, $attrs) {
                var data = "";
            }
        }
    })
    var moduleC = angular.module("moduleC", ["moduleA", "moduleB"]);
    moduleC.controller("Ctr", function ($scope) {
        $scope.item = {};
        $scope.item.dataAmount = 1000;
        $scope.item.templateUrl = "item-template.html";
    })
<body>
<div ng-app="moduleC">
    <div ng-controller="Ctr">
        <a-area>
            <my-item item="item" item-template="item.templateUrl"></my-item>
        </a-area>
    </div>
</div>
</body>
<div>
    <span style="display:block">hello every one</span>
    <b-span data="item.dataAmount"></b-span>
</div>
4。Html代码

    var moduleA = angular.module("moduleA", []);

    moduleA.directive("aArea", function () {
        return {
            restrict: 'E',
            transclude:'element',
            scope: {
                amount:"="
            },
            template: '<div id=\"cc\" ng-transclude></div>',
            controller: function ($scope,$element,$attrs) {
                this.getData = function (data) {
                    return data + " is ok";
                }
            },
            compile: function (tElement, attrs, linker) {
                var parentElement = tElement.parent();

                return {
                    pre: function () {

                    },
                    post: function (scope) {
                        linker(scope.$parent,function (clone,scope) {
                            parentElement.append(clone);
                        });
                        linker(scope.$parent, function (clone, scope) {
                            parentElement.append(clone);
                        });
                        linker(scope.$parent, function (clone, scope) {
                            parentElement.append(clone);
                        });
                    }
                }
            }
        }
    });

   moduleA.directive("bSpan", function () {
        return {
            restrict: 'E',
            scope: {
                data: "=",
            },
            template: '<span style=\"background-color:gray;color:orange\">{{data}}</span>',
            require: "^aArea",
            link: function ($scope, $element, $attrs, controller) {
                var data = "abc";
            }
        }
    });
    var moduleB = angular.module("moduleB", []);

    moduleB.directive("myItem", function () {
        return {
            restrict: 'E',
            scope: {
                item: "=",
                itemTemplate: '='
            },
            priority: 1000,
            terminal:false,
            template: '<ng-include src=\"itemTemplate\"/>',
            controller: function ($scope, $element, $attrs) {
                var data = "";
            }
        }
    })
    var moduleC = angular.module("moduleC", ["moduleA", "moduleB"]);
    moduleC.controller("Ctr", function ($scope) {
        $scope.item = {};
        $scope.item.dataAmount = 1000;
        $scope.item.templateUrl = "item-template.html";
    })
<body>
<div ng-app="moduleC">
    <div ng-controller="Ctr">
        <a-area>
            <my-item item="item" item-template="item.templateUrl"></my-item>
        </a-area>
    </div>
</div>
</body>
<div>
    <span style="display:block">hello every one</span>
    <b-span data="item.dataAmount"></b-span>
</div>

5。模板代码

    var moduleA = angular.module("moduleA", []);

    moduleA.directive("aArea", function () {
        return {
            restrict: 'E',
            transclude:'element',
            scope: {
                amount:"="
            },
            template: '<div id=\"cc\" ng-transclude></div>',
            controller: function ($scope,$element,$attrs) {
                this.getData = function (data) {
                    return data + " is ok";
                }
            },
            compile: function (tElement, attrs, linker) {
                var parentElement = tElement.parent();

                return {
                    pre: function () {

                    },
                    post: function (scope) {
                        linker(scope.$parent,function (clone,scope) {
                            parentElement.append(clone);
                        });
                        linker(scope.$parent, function (clone, scope) {
                            parentElement.append(clone);
                        });
                        linker(scope.$parent, function (clone, scope) {
                            parentElement.append(clone);
                        });
                    }
                }
            }
        }
    });

   moduleA.directive("bSpan", function () {
        return {
            restrict: 'E',
            scope: {
                data: "=",
            },
            template: '<span style=\"background-color:gray;color:orange\">{{data}}</span>',
            require: "^aArea",
            link: function ($scope, $element, $attrs, controller) {
                var data = "abc";
            }
        }
    });
    var moduleB = angular.module("moduleB", []);

    moduleB.directive("myItem", function () {
        return {
            restrict: 'E',
            scope: {
                item: "=",
                itemTemplate: '='
            },
            priority: 1000,
            terminal:false,
            template: '<ng-include src=\"itemTemplate\"/>',
            controller: function ($scope, $element, $attrs) {
                var data = "";
            }
        }
    })
    var moduleC = angular.module("moduleC", ["moduleA", "moduleB"]);
    moduleC.controller("Ctr", function ($scope) {
        $scope.item = {};
        $scope.item.dataAmount = 1000;
        $scope.item.templateUrl = "item-template.html";
    })
<body>
<div ng-app="moduleC">
    <div ng-controller="Ctr">
        <a-area>
            <my-item item="item" item-template="item.templateUrl"></my-item>
        </a-area>
    </div>
</div>
</body>
<div>
    <span style="display:block">hello every one</span>
    <b-span data="item.dataAmount"></b-span>
</div>

大家好

您不应该使用
编译
函数的transclude函数(您称之为
链接器
),它已被弃用

$compile

注意:传递给编译函数的
transclude
函数已被弃用,因为它不知道正确的外部作用域。请改用传递给link函数的TRANCLUDE函数

按照本指南(以及其他一些更好的小改动),更改
aArea
指令如下:

compile: function(tElement, tAttrs) {
  // don't use the template element 
  //var parentElement = tElement.parent();

  return function(scope, element, attrs, ctrls, transclude) {
      transclude(function(clone, scope) {
        element.after(clone);
      });
      transclude(function(clone, scope) {
        element.after(clone);
      });
      transclude(function(clone, scope) {
        element.after(clone);
      });
  };
}

事实上,您甚至根本不需要
transclude
函数,也不需要执行
transclude:“element”
。您可以更改为
transclude:true
并在模板中使用
三次。

太好了,您的建议在应用程序中是有意义的。但这只是一个与我的实际应用程序相关的简单示例。即使我在link函数中使用了transclude函数,它也找不到所需的控制器。那么是什么原因导致了这种问题?@RonSmith,这应该可以正常工作。我在plunker中复制了您的示例,答案中建议的修复方法使其有效:首先,我感谢您的答案,并且该示例确实与上面的答案非常吻合。因为它在我的实际应用程序中更复杂,所以我只是模仿它来创建这个示例。但有了答案,实际的应用程序仍然存在这个问题。所以我想知道潜在的原因,我可以有方向去接近它。@RonSmith如果不花几个小时深入Angular的来源,很难说。不知何故,当您使用编译的transclude时,父元素
aArea
的数据中没有设置控制器,因此会触发此错误。不过,感谢您的反馈。这个问题让我困惑了大约两周。虽然在简单的演示中可以解决,但在实际应用中,有两个第三方指令不能很好地协同工作,我只需要接近它,但我不知道找到原因并修复它。这是简单副本的ulr,如果您能帮我审阅,我将不胜感激。