如何将隔离作用域指令中的变量传递给子元素?

4
我有两个隔离作用域指令。理想情况下,我希望两者都能独立工作,而不需要任何自定义模板。第一个指令将成为页面滚动监视器,当它到达某个点时,我希望它会触发另一个指令的更新。子指令是否可以监视父指令中的变量?
我创建了一个简单的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

通常访问父级作用域并不是一个好的实践。你可以使用 $scope.$parent。 - UserNeD
虽然这是正确的,但如果您以这种方式进行操作,则会出现一些错误。由于子作用域在原型上继承父作用域,因此您不需要这样做。当代码增长时,这将变得混乱,并且您将发现自己编写$parent.$parent.$parent.$parent.help()。 - UserNeD
1
如果在同一页上有多个指令实例,则共享服务将无法正常工作。 - fatlinesofcode
如果您按顺序设置和获取sharedValue,则该值将被同步。此外,Javascript是一种单线程语言。 - UserNeD

0

将变量从父指令传递到子指令的第一种方法是在子作用域中使用'@'的'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;

  }
]);

谢谢回复。我看了第二种方法。有几个问题。http://plnkr.co/edit/TFWtf20hKSKnEaKZbZIb?p=preview 第一个问题是似乎不使用模板就无法工作。第二个问题是将require添加到内部指令会创建对外部指令的依赖性。我想选择在没有外部指令的情况下使用内部指令。 - fatlinesofcode
我通过控制器公开父级范围来使其工作。然后,我可以监视子指令中的变量。但是,我仍然需要使用 require ,因此只有在父指令包装子指令时才能起作用。理想情况下,我希望父指令是可选的。还有其他方法可以采取吗?http://plnkr.co/edit/VcTgMm7zu78XE681d17w?p=preview - fatlinesofcode
虽然这是正确的,但如果您以这种方式进行操作,则会出现一些错误。由于子作用域在原型上从父作用域继承,因此您不需要这样做。当代码增长时,这将变得混乱,您将发现自己编写$parent.$parent.$parent.$parent.help()。您需要将API控制器制作为一个并将其传递给指令范围作为“^apiCtrl”。 - UserNeD
第三种方法:您可以将服务注入到内部和外部指令中。然后使用该服务。 - UserNeD

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接