将子指令数据传递给父指令

时间:2017-01-30 03:18:02

标签: javascript angularjs

如何将子属性指令的范围或attr值传递给父指令?

给定widget指令,使用in-viewport属性指令,我希望每次滚动文档时更新属性inView,并将更新后的值传递给父指令{{1 }}:

widget

在Viewport指令中:作为父指令" widget"

的属性传入
<widget in-viewport></widget>

小部件指令:

angular.module('app').directive('inViewport', function() {
    return {
      restrict: 'A',
      scope: false, // ensure scope is same as parents
      link: function(scope, element, attr) {
        angular.element(document).on('scroll', function() {
          // I've tried binding it to attr and parent scope of "widget" directive

          attr.inView = isElementInViewport(element);
          scope.inView = isElementInViewport(element);
        });
      }
    };
  });

3 个答案:

答案 0 :(得分:1)

您可以在父指令上公开API,并使用isolateScope()来访问它。

这是一个有效的fiddle

var app = angular.module("app",[]);

app.directive("widget", function($rootScope){
        return {
        template: "<div>Scroll this page and widget will update. Scroll Y: {{scrollPosY}}</div>",
      scope: {},  // <-- Creating isolate scope on <widget>.  This is REQUIRED.
      controller: ['$scope', function DirContainerController($scope) {
        $scope.scrollPosY = 0;
        // Creating an update function.
        $scope.update = function(position) {
          $scope.scrollPosY = position;
          $scope.$digest();
        };
      }],
    }
});

app.directive("inViewport", function($window, $timeout, $rootScope){
        return {
      restrict: 'A',
      link:function(scope, element, attrs, parentCtrl){
        // Get the scope.  This can be any directive.
        var parentScope = element.isolateScope();
        angular.element(document).on('scroll', function() {
          // As long as the parent directive implements an 'update()' function this will work.
          parentScope.update($window.scrollY);
          console.log('parentScope: ', parentScope);
        });
      }
    }
});

答案 1 :(得分:1)

以下是访问父指令变量的方法,

angular.module('myApp', []).directive('widget', function() {
    return {
        restrict: 'E',
        template: '<viewport in-view="variable"></viewport> <h1>{{variable}}</h1>',
        link: function(scope, iAttrs) {

            scope.variable = 10;
        }
    }
}).directive('viewport', function() {
    return {
        restrict: 'E',
        scope: {
                inView: "=",
            },
        template: '<button ng-click="click()">Directive</button>',
        link: function(scope, iElement, iAttrs) {
                        scope.click = function() {
                scope.inView++;
            }
        }
    }
});

<强> HTML

<div ng-app="myApp" ng-controller="Ctrl1">
    <widget></widget>
</div>

这是工作的jsfiddle http://jsfiddle.net/p75DS/784/

如果您有任何疑问,请在评论栏中询问

答案 2 :(得分:1)

这是一个使用你的指令结构的工作小提琴: http://jsfiddle.net/ADukg/9591/

标记是这样的:

<div ng-controller="MyCtrl" style="height: 1200px;">
  {{name}}
  <hr>
  <widget in-viewport></widget>
</div>

只需滚动窗口即可触发事件。请注意,指令只是为了证明var得到更新...

var myApp = angular.module('myApp',[]);

myApp.directive('inViewport', function($timeout) {
    return {
      restrict: 'A',
      scope: false, // ensure scope is same as parents
      link: function(scope, element, attr) {
        angular.element(window).bind('scroll', function() {
          console.log('Called');
          $timeout(function() {
            scope.inView++;
          }, 0);
        });
      }
    };
  });

  myApp.directive('widget', function() {
    return {
      restrict: 'AE',
      transclude: false,
      template: '<p>This is a widget</p>',
      link: function(scope) {
        scope.inView = 0;
        console.log('In Viewport: ', scope.inView); // Null

        scope.$watch('inView', function(newVal, oldVal) {
            console.log('Updated by the child directive: ', scope.inView);
        });
      }
    }
  });

function MyCtrl($scope) {
    $scope.name = 'Angular Directive Stuff';
}