【问题标题】:ScrollSpy directive that talks to controller in AngularJS与 AngularJS 中的控制器对话的 ScrollSpy 指令
【发布时间】:2014-02-20 18:16:33
【问题描述】:

我是 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";
}]);

现在基本上我想要一个滚动间谍,只要该项目当前位于顶部视口:

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 种不同的速记,而且它们并不总是能很好地结合在一起。任何帮助表示赞赏,包括风格指导。

【问题讨论】:

    标签: javascript angularjs angularjs-directive scrollspy


    【解决方案1】:

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

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

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

    -----------编辑----

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

    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;
                })
    
            }
        }
    });
    

    【讨论】:

    • 好的,我可以设置scope: false 来共享父级的作用域——但我仍然无法操纵它。更改其中的任何内容只会更改子范围中的属性。一个代码示例会非常有帮助!
    • 我希望他的小例子能帮助你做你想做的事。
    • 感谢编辑!重点不是访问父作用域,而是改变它以更新 HTML。设置scope.header = "Foo" 并不会真正改变控制器的作用域,scope.$parent.header = "Foo" 也不会。
    • @Manuel 我做了一些更改,并且知道它有效。我不完全确定它是否具有良好的性能,也许还有其他更好的方法。
    • 哈,$apply 是关键!非常感谢!!
    猜你喜欢
    • 1970-01-01
    • 2013-03-15
    • 1970-01-01
    • 2015-09-24
    • 1970-01-01
    • 2014-01-03
    • 1970-01-01
    • 1970-01-01
    • 2013-05-28
    相关资源
    最近更新 更多