【问题标题】:How can I pass variables from an isolated scope directive to a child?如何将变量从隔离范围指令传递给孩子?
【发布时间】:2015-05-05 01:28:25
【问题描述】:

我有两个独立的作用域指令。理想情况下,我喜欢两者独立工作,不需要任何自定义模板。第一个指令将是页面滚动观察器,当它达到某个点时,我希望它触发另一个指令中的更新。子指令是否可以监视父指令中的变量?

我创建了一个简单的 plunkr 来说明这个问题,http://plnkr.co/edit/wwfBzmemyrj1r1R54riM?p=preview

    /*
 <div ng-outer>Outer directive {{myvar}}
      <div ng-inner="myvar">Inner directive</div>
    </div>
    */
app.directive('ngOuter', [ '$timeout', function ($timeout) {
    var directive = {
        restrict: 'A'
        ,scope:{}
    }
    directive.link = function (scope, element, attrs) {
        $timeout(function(){
          scope.myvar = "test 001"
        },1000)
    }
    return directive;

}]);

app.directive('ngInner', [ function () {
    var directive = {
        restrict: 'A'
        ,scope:{ data: '=ngInner',  myvar: '=myvar' }
    }
    directive.link = function (scope, element, attrs) {
        scope.$watch('data', function(newVal, oldVal){
          if(newVal)
          element.text("new inner val", newVal);
        });
          scope.$watch('myvar', function(newVal, oldVal){
          if(newVal)
          element.text("new myvar", newVal);
        });


    }

    return directive;

}]);

【问题讨论】:

    标签: angularjs angularjs-directive


    【解决方案1】:

    通过使用解决了这个问题

    angular.element(element.parent()).isolateScope();
    

    子指令可以访问父指令的范围和监视变量等。

    http://plnkr.co/edit/RAO6q81ZE4tClMDMiLFb?p=preview

    【讨论】:

    • 通常访问 orent 范围不是一个好习惯。您也可以使用 $scope.$parent。
    • 虽然这是真的,但如果你这样做,你做错了一些事情。由于子作用域原型继承自父作用域,因此您不需要这样做。当代码增长时会很乱,你会发现自己在写 $parent.$parent.$parent.$parent.help()
    • 如果您在同一页面上有多个指令实例,则共享服务将无法工作
    • 如果您按顺序设置并获取 sharedValue ,则该值将被同步。 Javascript也是一种单线程语言。
    【解决方案2】:

    将变量从父指令传递给子指令的第一种方法是在子作用域中使用带有“@”的“attr”并在父控制器中将其初始化如下:

    var app = angular.module('app', []);
    
    app.directive('ngOuter', [ '$timeout', function ($timeout) {
        return{
           restrict: 'E',
           scope:{},
           template: '<ng-inner attr="{{myvar}}">Inner directive {{myvar}}</ng-inner>',
           controller: ['$scope', function($scope) {
                $scope.myvar = "test 001";
           }],
           link: function (scope, elem, attrs) {
    
           }
        }
    }]);
    
    app.directive('ngInner', [ function () {
        return{
           restrict: 'E',
           scope:{'attr' : "@"},
           link: function (scope, element, attrs) {
               console.log(scope.attr);
           } 
        }
    }]);
    

    html:

        <ng-outer></ng-outer>
    

    第二种方法是在父控制器中使用一个函数,该函数返回“myvar”值并在子指令中调用该函数:

    app.directive('ngOuter', [ '$timeout', function ($timeout) {
        return{
            restrict: 'E',
            scope:{},
            template: '<ng-inner attr="{{myvar}}">Inner directive {{myvar}}</ng-inner>',
            controller: ['$scope', function($scope) {
                $scope.myvar = "test 001";
                this.getMyvar = function() {
                    return $scope.myvar;
                };
            }],
            link: function (scope, elem, attrs) {
    
           }
       }
    
    }]);
    
    app.directive('ngInner', [ function () {
        return{
            restrict: 'E',
            require: '^ngOuter',
            scope:{'attr' : "@"},
            link: function (scope, element, attrs, parentDirCtrl) {
                console.log(parentDirCtrl.getMyvar());
            } 
        }
    
    }]);
    

    第三种方法:您可以向内部和外部指令注入服务。然后使用该服务。

    var app = angular.module('app', []);
    
    
    app.service('myService', [
      function() {
        var service = {
          myvar: 'test001',
          setMyVar: function(value) {
            this.myvar = value;
          },
          getMyVar: function() {
            return this.myvar;
          }
        }
        return service;
      }
    ]);
    
    
    
    app.directive('ngOuter', ['$timeout', 'myService',
      function($timeout, myService) {
        var directive = {
          restrict: 'A',
          scope: {}
        }
        directive.link = function(scope, element, attrs) {
          $timeout(function() {
            scope.myvar = myService.getMyVar();
          }, 1000)
        }
        return directive;
    
      }
    ]);
    
    app.directive('ngInner', ['myService',
      function(myService) {
        var directive = {
          restrict: 'A',
          scope: {}
        }
        directive.link = function(scope, element, attrs) {
          var variable = myService.getMyVar();
          console.log("myvar", variable);
        }
        return directive;
    
      }
    ]);
    

    【讨论】:

    • 感谢您的回复。我看了第二种方法。几个问题。 plnkr.co/edit/TFWtf20hKSKnEaKZbZIb?p=preview 首先是不使用模板似乎无法工作。向内部指令添加 require 的第二个问题创建了对外部指令的依​​赖。我想选择使用内部指令而不使用外部指令。
    • 我设法通过控制器公开父范围来使其工作。然后我可以从子指令中观察一个变量。但是我仍然需要使用require,因此子指令只有在被父包裹时才具有功能。理想情况下,我希望父指令是可选的。我可以采取另一种方法吗? plnkr.co/edit/VcTgMm7zu78XE681d17w?p=preview
    • 虽然这是真的,但如果你这样做,你做错了一些事情。由于子作用域原型继承自父作用域,因此您不需要这样做。当代码增长时会很混乱,你会发现自己在编写 $parent.$parent.$parent.$parent.help()。您需要将 API 控制器作为“^apiCtrl” 传递给指令范围
    • 第三种方法:您可以向内部和外部指令注入服务。然后使用该服务。
    猜你喜欢
    • 2014-10-12
    • 2013-04-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多