transclude不起作用

我正在编写两个包含ui-bootstrap的tabset和tab指令的指令。
为了将我的指令的内容传递给包装的指令,我在两个指令中都使用了transclusion。
这工作得很好,唯一的问题是我没有编写一个测试来检查它。 我的测试使用替换指令作为包装指令的模拟,我在每次测试之前使用$ compileProvider替换。

测试代码如下所示:

beforeEach(module('myModule', function($compileProvider) {
    // Mock the internally used 'tab' which is a third party and should not be tested here
    $compileProvider.directive('tab', function() {
        // Provide a directive with a high priority and 'terminal' set to true, makes sure that
        // the mock directive will get executed, and that the real directive will not
        var mock = {
            priority: 100,
            terminal: true,
            restrict: 'EAC',
            replace: true,
            transclude: true,
            template: '<div class="mock" ng-transclude></div>'
        };

        return mock;
    });
}));

beforeEach(function() {
    inject(function(_$compile_, _$rootScope_) {
        $compile = _$compile_;
        $rootScope = _$rootScope_;
    });
});

beforeEach(function() {
    $scope = $rootScope.$new();
});

afterEach(function() {
    $scope.$destroy();
});

it('Places the enclosed html inside the tab body', function() {
    element = $compile("<div><my-tab>test paragraph</my-tab></div>")($scope);
    $scope.$digest();

    console.log("element.html() = ", element.html());

    expect(element.text().trim()).toEqual("test paragraph");
});

我的指令模板如下所示:

<div><tab><div ng-transclude></div></tab></div>

指令模块看起来像这样:

angular.module('myModule', ['ui.bootstrap'])

.directive('myTab', function() {
    return {
        restrict: 'E',
        replace: true,
        transclude: true,
        templateUrl: 'templates/my-tab.tpl.html',

        scope: {
        }
    };
});

打印到控制台的结果是这样的:

LOG: 'element.html() = ', '<div class="ng-isolate-scope" id=""><div id="" heading="" class="mock"><ng-transclude></ng-transclude></div></div>'

关于为什么不会发生跨越的任何想法(再次,它在测试之外工作就好了)?

更新

我已经转向其他事情和指示,并再次遇到这个问题,但现在更重要的是,原因是,我放置在父指令内部的指令需要父控制器在其链接函数中。

我已经做了更多的研究,结果发现,由于某种原因,编译mock指令不会创建transcluded内容的实例。
我知道的原因是,我已经在两个指令(包括模拟和transcluded指令)中的每一个可能的钩子上放置了一个打印输出,即编译,预链接,后链接和控制器构造函数,并且我看到只有打印输出来自模拟指令。

现在,下面是一个非常有趣的部分:我试图在mock指令的链接函数中使用transclude函数来“强制”编译transcluded指令,该指令工作正常! (另一个证据表明它不是隐含的)。
你问的问题在哪里? 那么,它仍然不起作用。 这一次,因为transcluded指令的链接函数失败,因为它找不到mock指令的控制器。 什么 ?!

代码如下:

var mod = angular.module('MyModule', []);

mod.directive('parent', function() {
    return {
        restrict: 'E',
        replace: true,
        template: '<div class="parent">...</div>',

        controller: function() {
            this.foo = function() { ... };
        }
    };
});

mod.directive('child', function() {
    return {
        restrict: 'E',
        require: '^parent',        

        link: function(scope, element, attrs, parentCtrl) {
            parentCtrl.foo();
        }
    };
});

测试

describe('child directive', function() {
    beforeEach(module('MyModule', function($compileProvider) {
        $compileProvider.directive('parent', function() {
            return {
                priority: 100,
                terminal: true,
                restrict: 'E',
                replace: true,
                transclude: true,

                template: '<div class="mock"><ng-transclude></ng-transclude></div>',

                controller: function() {
                    this.foo = jasmine.createSpy();
                },

                link: function(scope, element, attrs, ctrls, transcludeFn) {
                    transcludeFn();
                }
            };
        });
    }));
});

此测试失败,并显示以下错误消息:

错误:[$ compile:ctreq]无法找到指令'child'所需的控制器'parent'!

任何想法,想法,建议将不胜感激。


好吧,可能是有史以来最短的奖金...

问题出在terminal: truepriority: 100 mock指令的priority: 100属性。 我的印象(从我在线阅读的关于如何模拟指令的文章中),这些属性会导致编译器停止编译具有相同名称的指令,并优先考虑mock指令的优先级。
我显然是错的。 看这个和这个,变得清楚的是:

  • '终端'停止任何尚未处理的其他指令被处理
  • 'priority'用于确保mock指令在它嘲笑的指令之前被处理
  • 问题是,这会导致所有其他处理停止,包括ng-transclude指令,其默认优先级为0

    然而,除去这些属性会导致所有的地狱崩溃,因为这两个指令都已经被注册了,等等(我不会给你所有的血腥细节带来负担)。 为了能够删除这些属性,这两个指令应该驻留在不同的模块中,并且它们之间不应该存在依赖关系。 简而言之,在测试child指令时,唯一被评估的名为parent的指令应该是mock指令。
    为了支持现实生活中的使用,我为系统引入了三个模块:

  • 用于child指令的模块(不依赖)
  • parent指令模块(不依赖)
  • 没有内容,但对两者的相关性模块childparent模块,这是你永远需要添加在你的代码的依赖的唯一模块
  • 这是非常多的。 我希望它能帮助其他任何遇到这种问题的人。

    链接地址: http://www.djcxy.com/p/83997.html

    上一篇: transclude doesn't work

    下一篇: How to Add More than One Item to Middleware on Route in Laravel 5