与AngularJS中的控制器通信的ScrollSpy指令

时间:2014-02-20 18:16:33

标签: javascript angularjs angularjs-directive scrollspy

我是AngularJS的新手,已经处于绝望的边缘:)我的应用程序看起来像这样(Not-working example on Plnkr):

HTML

<div ng-app="myApp" ng-controller='controllers.content' >
  <h2 id="fixed">{{ header }}</h2>
  <ul>
    <li ng-repeat="item in db" scroll-stop="item">{{ item.name }}</li>
  </ul>
</div>

JS

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

var app = angular.module('myApp.controllers').controller('controllers.content', ['$scope', function($scope){
    $scope.db = [
      { name: "20 February 2014", header: "Today" },
      // ...
    ];
    $scope.header = "Today";
}]);

现在基本上我想要一个滚动间谍,将h2的内容(假设它固定在顶部)更改为header项目的db属性,只要该项目是目前位于视口的顶部:

app.directive('scrollStop', function() {
   return {
        restrict: 'A',
        scope: {
          scrollStop:'='
        },
        link: function (scope, element, attrs) {

            var $page = angular.element(window)
            var $el   = element[0]
            var last_top = $el.getBoundingClientRect().top - 60;
            $page.bind('scroll', function () {
                var current_top = $el.getBoundingClientRect().top - 60;
                if (last_top >= 0 && current_top < 0) {
                    // HERE!
                    console.log(scope.scrollStop.header);
                    scope.header = scope.scrollStop.header;
                }
                last_top = current_top;
            })

        }
    }
});

但是,我无法弄清楚如何从指令中的content控制器与指令内的编辑 $scope.header进行对话。我理解scope与控制器的$scope不同,并且有一种模糊的感觉,我应该在某个地方使用require,但无法弄清楚如何正确使用它。部分原因还在于,在AngularJS中做任何事情似乎有5个不同的缩写,并且它们并不总能很好地结合在一起。任何帮助,包括风格指导。

1 个答案:

答案 0 :(得分:2)

您正在为指令使用隔离范围。因此,您可以访问范围控制器。您可以使用服务或使用事件与控制器通信。

如果您希望能够直接从您的指令访问控制器范围,则必须使用共享范围。

我希望它有所帮助。您可以在指令Here中找到有关范围的更多信息。

----------- EDIT ----------------

我不确定您想要做什么,但在下一个代码中您可以看到使用共享范围,您可以从de parent访问数据并使用新数据刷新视图。

angular.module('app').directive('scrollStop', function() {
    return {
        restrict: 'A',
        scope: false,
        link: function (scope, element, attrs) {

            var $page = angular.element(window)
            var $el   = element[0]
            var last_top = $el.getBoundingClientRect().top - 60;
            $page.bind('scroll', function () {
                var current_top = $el.getBoundingClientRect().top - 60;
                if (last_top >= 0 && current_top < 0) {
                    // HERE!
                    scope.$parent.header=scope[attrs.scrollStop].header;
                    scope.$parent.$apply();
                }
                last_top = current_top;
            })

        }
    }
});