如何将变量从隔离范围指令传递给子节点?

时间:2023-01-03 22:52:06

I have two isolated scope directives. Ideally I like both to work independently and not require any custom templates. The first directive is going to be page scroll watcher, when it hits a certain point I want it to trigger an update in the other directive. Is it possible for a child directive to watch a variable in the parent directive?

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

I've created a simple plunkr to illustrate the issue, http://plnkr.co/edit/wwfBzmemyrj1r1R54riM?p=preview

我已经创建了一个简单的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;

}]);

2 个解决方案

#1


1  

Solved this issue by using

通过使用解决了这个问题

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

The child directive can access the scope of the parent directive and watch variables etc.

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

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

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

#2


0  

First approach of passing variable from parent directive to the child is by using an 'attr' in child scope with '@' and initialize it in parent controller as following:

将变量从父指令传递给子节点的第一种方法是使用子节点中的'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:

HTML:

    <ng-outer></ng-outer>

2nd approach is utilizing a function in a parent controller which returns the "myvar" value and call that function in child directive:

第二种方法是在父控制器中使用一个函数,该函数返回“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());
        } 
    }

}]);

3rd Approach: you can inject a service to both inner and outer directives.Then use the service.

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

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;

  }
]);

#1


1  

Solved this issue by using

通过使用解决了这个问题

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

The child directive can access the scope of the parent directive and watch variables etc.

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

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

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

#2


0  

First approach of passing variable from parent directive to the child is by using an 'attr' in child scope with '@' and initialize it in parent controller as following:

将变量从父指令传递给子节点的第一种方法是使用子节点中的'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:

HTML:

    <ng-outer></ng-outer>

2nd approach is utilizing a function in a parent controller which returns the "myvar" value and call that function in child directive:

第二种方法是在父控制器中使用一个函数,该函数返回“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());
        } 
    }

}]);

3rd Approach: you can inject a service to both inner and outer directives.Then use the service.

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

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;

  }
]);