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
                });

            };
        }
    };
})

デモ

または、リンク関数でトランスクルード関数を使用します。

.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 に答える