1

我想在我的其他指令中添加我的自定义指令。第二个指令应该使用第一个指令的范围。问题是第一个指令具有隔离范围,并且显然它对于第二个指令也是隔离的,在我看来它不应该因为我使用的是 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 中,情况似乎发生了变化,并且包含范围是链上更高的下一个范围的子范围。

要解决此问题,您只需将 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 回答
1

您可以访问 $parent 范围 ex。$parent.myVar。仅适用于角度 1.3

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

            });
    angular.module('myApp')
            .directive('firstDirective', ['$timeout', function ($timeout) {
                return {
                    restrict: 'E',
                    scope: {
                        test:"@",
                        //myVar:"="
                    },
                    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);
                this.getMyVar = function () {
                    return $scope.myVar;
                };
                //console.log($scope.getMyVar());
            }])
            .directive('secondDirective', [function () {
                return {
                    restrict: 'E',
                    scope: false,
                    require: "^firstDirective",
                    template: '<div> Second Directive {{$parent.myVar}}</div>',
                    link: function (scope, element, attributes, ctrl) {
                        //console.log(scope.$parent);
                        //console.log(ctrl);
//                        console.log(ctrl.myVar);
//                        console.log(ctrl.getMyVar());
                        //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.3.8/angular.min.js"></script>
    <title></title>
</head>
<body>
<div ng-controller="initCtrl" class="container">
    <first-directive test="test">
        {{$parent.myVar}}
        <second-directive></second-directive>
    </first-directive>
</div>
</body>
</html>

于 2015-01-12T10:34:15.497 回答