11

是我的脚本:

angular.module('MyApp',[])
.directive('mySalutation',function(){
    return {
        restrict:'E',
        scope:true,
        replace:true,
        transclude:true,
        template:'<div>Hello<div ng-transclude></div></div>',
        link:function($scope,$element,$attrs){
        }
    };
})
.controller('SalutationController',['$scope',function($scope){
    $scope.target = "StackOverflow";
}])

和html:

<body ng-app="MyApp">
    <my-salutation ng-controller="SalutationController">
        <strong>{{target}}</strong>        
    </my-salutation>
</body>

问题是,当SalutationController应用于my-salutation指令时,对于嵌入的元素$scope.target 是不可见ng-controller的。但如果我穿上<body>或穿上<strong>元素,它就可以工作。正如文档所说,ng-controller创建了新的范围。

  • 谁能解释一下,在这种情况下,该范围和指令的范围如何相互干扰?

  • 如何将控制器置于指令上?任何提示将不胜感激。

4

2 回答 2

9

1)问题是ng-transclude' 的范围是你的指令的兄弟范围。当您将 放置ng-controller到父元素时,由创建的ng-controller范围是您的指令的父范围和ng-transclude. 由于范围继承,被嵌入的元素能够{{target}}正确绑定。

2)您可以使用自定义嵌入来自己绑定范围

.directive('mySalutation',function(){
    return {
        restrict:'E',
        scope:true,
        replace:true,
        transclude:true,
        template:'<div>Hello<div class="transclude"></div></div>',
        compile: function (element, attr, linker) {
            return function (scope, element, attr) {
                linker(scope, function(clone){
                       element.find(".transclude").append(clone); // add to DOM
                });

            };
        }
    };
})

演示

或者在链接函数中使用 transclude 函数:

.directive('mySalutation',function(){
    return {
        restrict:'E',
        scope:true,
        replace:true,
        transclude:true,
        template:'<div>Hello<div class="transclude"></div></div>',
        link: function (scope, element, attr,controller, linker) {
           linker(scope, function(clone){
                  element.find(".transclude").append(clone); // add to DOM
           });
        }
    };
})

演示

于 2014-03-22T09:11:31.487 回答
2

要使指令和控制器具有相同的范围,您可以手动调用 transcludeFn:

angular.module('MyApp',[])
.directive('mySalutation',function(){
    return {
        restrict:'E',
        scope:true,
        replace:true,
        transclude:true,
        template:'<div>Hello<div class="trans"></div></div>',
        link:function(scope, tElement, iAttrs, controller, transcludeFn){
                console.log(scope.$id);
                transcludeFn(scope, function cloneConnectFn(cElement) {
                    tElement.after(cElement);
                }); 
        }
    };
})
.controller('SalutationController',['$scope',function($scope){
    console.log($scope.$id);
    $scope.target = "StackOverflow";
}]);

笨拙

您可以看到 '003' 每次都被注销,并且您的代码通过这个微小的调整按预期工作。

于 2014-03-22T09:16:40.393 回答