隔离范围也适用于转录?

时间:2015-01-12 09:34:29

标签: angularjs scope angularjs-scope angularjs-ng-transclude

我想在我的其他指令中添加我的自定义指令。 第二个指令应该使用第一个指令的范围。 问题是第一个指令具有孤立的范围,并且显然它也被隔离用于第二个指令,在我看来它不应该因为我使用了转换。

这是一个例子。当我评论scope: {test:"@"}所有的wroks时应该这样做。 怎么解决?



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";
                    }
                };
            }]);
&#13;
<!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>
&#13;
&#13;
&#13;

2 个答案:

答案 0 :(得分:1)

这是因为第一个指令使用隔离范围,myVar在指令模板中不可见。 myVar在已转换内容中可见,因为它链接到转换作用域,该作用域是父控制器作用域的子作用域。 translude范围和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>

答案 1 :(得分:1)

您可以访问$ parent scope 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>