在动态生成的AngularJS指令中访问父控制器

时间:2014-07-26 04:57:04

标签: angularjs angularjs-directive

我有一些项目存储在数据库中。每个项目都有一个'类型'。我想使用此类型根据类型动态插入指令。我的HTML看起来像:

<ul>
  <li my-item ng-repeat="item in items"></li>
</ul

my-item指令中,我动态生成一个指令,如下所示:

app.directive('myItem', function($compile){
    return {
        link: function(scope, el, attrs) {
            var concreteTypeEl = $compile('<div my-item-' + scope.item.type + ' item="item"></div>')(scope);
            el.append(concreteTypeEl);
        }
    };
});

然后我有进一步的指令定义'具体'项目类型。例如,类型为“Type1”的项目将使用“myItemType1”指令(如下所示)

所以这一切都很好。现在,我还想要一个父指令来包装这些指令的所有实例,并提供一个控制器来允许它们之间的协调。

我使用require ^parentCtrl指令上的myItem语法来访问父控制器。

我的问题是,这不适用于任何'动态'插入的指令,例如'myItemType1'

下面和plunkr中的完整示例。标记:

<body ng-controller="MainCtrl">
    <div my-container>
        <ul>
            <li my-item ng-repeat="item in items"></li>
        </ul>
    </div>
</body>

代码:

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
    $scope.items = [{
        type: 'type1',
        content: 'Type 1 item'
    }, {
        type: 'type1',
        content: 'Another Type 1 item'
    }];
});

app.directive('myContainer', function(){
    return {
        controller: function() {
            this.doSomething = function() {
                return 'foo';
            }
        }
    };
});

app.directive('myItem', function($compile){
    return {
        require: '^myContainer',
        link: function(scope, el, attrs, myContainer) {

            // 'myContainer' is a reference to parent controller
            console.log('Ctrl in myItem:', myContainer);

            var concreteTypeEl = $compile('<div my-item-' + scope.item.type + ' item="item"></div>')(scope);
            el.append(concreteTypeEl);
        }
    };
});

app.directive('myItemType1', function($compile){
    return {
        require: '?^myContainer',
        link: function(scope, el, attrs, myContainer) {

            // PROBLEM: 'myContainer' is undefined here
            console.log('Ctrl in myItemType1:', myContainer);

            el.append(scope.item.content);
        }
    };
});

我接近这一切都错了吗?

1 个答案:

答案 0 :(得分:3)

在手动编译和链接之前,您应该将元素附加到DOM树:

link:function(scope,element,attr) {
    // create the element
    var e = angular.element('<my-child></my-child>');           
    //append it to the DOM  
    element.append(e);
    // compile and link
    $compile(e)(scope);
}

Demo Fiddle