1

カスタム ディレクティブを他のディレクティブ内に追加したいと考えています。2 番目のディレクティブは、最初のディレクティブのスコープを使用する必要があります。問題は、最初のディレクティブのスコープが分離されており、明らかに 2 番目のディレクティブでも分離されていることです。私の意見では、transclude を使用しているため、そうすべきではありません。

これが例です。私がコメントするとscope: {test:"@"}、すべてが正常に機能します。修正方法は?

angular.module("myApp", [])
            .controller("initCtrl", function ($scope) {

            });
    angular.module('myApp')
            .directive('firstDirective', ['$timeout', function ($timeout) {
                return {
                    restrict: 'E',
                    scope: {test: "@"}, //everything is OK when I comment that.
                    transclude: true,
                    template: '<div> First Directive {{myVar}} {{test}}<div ng-transclude></div></div>',
                    controller: "firstDirectiveCtrl",
                    link: function (scope, element, attributes) {

                    }
                };
            }])
            .controller("firstDirectiveCtrl", ['$scope', '$timeout', function ($scope, $timeout) {
                $scope.myVar = "Var from first directive";
                $timeout(function () {
                    $scope.myVar = "Var from first directive has changed";
                }, 1000);
            }])
            .directive('secondDirective', [function () {
                return {
                    restrict: 'E',
                    scope: false,
                    require: "^firstDirective",
                    template: '<div> Second Directive {{myVar}}</div>',
                    link: function (scope, element, attributes) {
                        //scope.myVar = "Var from second directive";
                    }
                };
            }]);
<!DOCTYPE html>
<html data-ng-app="myApp">
<head lang="en">
    <meta charset="UTF-8">
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    <title></title>
</head>
<body>
<div ng-controller="initCtrl" class="container">
    <first-directive test="test">
        <second-directive></second-directive>
        {{myVar}} 
<br><i>no var unless I comment scope: {test:"@"} i first directive.</i>
    </first-directive>
</div>
</body>
</html>

4

2 に答える 2

1

最初のディレクティブが分離スコープを使用しているため、ディレクティブのテンプレート内で myVar が表示されません。myVar は、親コントローラー スコープの子スコープであるトランスクルージョン スコープにリンクされているため、トランスクルージョンされたコンテンツ内に表示されます。トランスクルージョン スコープと firstDirective の分離スコープは姉妹スコープですが、互いに分離しています。

注: これは 1.2+ にのみ当てはまります。1.3 では状況が変わったようで、transclusion スコープは、チェーンの上位にある次のスコープの子スコープです。

これを修正するには、myVar を分離スコープに渡すだけです。

.directive('firstDirective', ['$timeout', function ($timeout) {
    return {
        restrict: 'E',
        scope: {test: "@", myVar: "="}, //pass myVar into your isolated scope.
        transclude: true,
        template: '<div> First Directive {{myVar}} {{test}}<div ng-transclude></div></div>',
        controller: "firstDirectiveCtrl",
        link: function (scope, element, attributes) {

        }
    };
}])

HTML

<div ng-controller="initCtrl" class="container">
    <first-directive test="test" my-var="myVar">
        <second-directive></second-directive>
        {{myVar}} 
        ...
    </first-directive>
</div>

angular.module("myApp", [])
            .controller("initCtrl", function ($scope) {

            });
    angular.module('myApp')
            .directive('firstDirective', ['$timeout', function ($timeout) {
                return {
                    restrict: 'E',
                    scope: {test: "@", myVar:"="}, //everything is OK when I comment that.
                    transclude: true,
                    template: '<div> First Directive {{myVar}} {{test}}<div ng-transclude></div></div>',
                    controller: "firstDirectiveCtrl",
                    link: function (scope, element, attributes) {

                    }
                };
            }])
            .controller("firstDirectiveCtrl", ['$scope', '$timeout', function ($scope, $timeout) {
                $scope.myVar = "Var from first directive";
                $timeout(function () {
                    $scope.myVar = "Var from first directive has changed";
                }, 1000);
            }])
            .directive('secondDirective', [function () {
                return {
                    restrict: 'E',
                    scope: false,
                    require: "^firstDirective",
                    template: '<div> Second Directive {{myVar}}</div>',
                    link: function (scope, element, attributes) {
                        //scope.myVar = "Var from second directive";
                    }
                };
            }]);
<!DOCTYPE html>
<html data-ng-app="myApp">
<head lang="en">
    <meta charset="UTF-8">
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
    <title></title>
</head>
<body>
<div ng-controller="initCtrl" class="container">
    <first-directive test="test" my-var="myVar">
        <second-directive></second-directive>
        {{myVar}} 
<br><i>no var unless I comment scope: {test:"@"} i first directive.</i>
    </first-directive>
</div>
</body>
</html>

于 2015-01-12T09:51:19.877 に答える