【问题标题】:Binding directive scope with controller in AngularJS在AngularJS中将指令范围与控制器绑定
【发布时间】:2016-05-23 10:54:22
【问题描述】:

我正在使用指令来检查用户滚动窗口的程度,但我无法将范围与控制器绑定。

这是指令和控制器代码:

'use strict';

angular.module('myApp.landing', ['ngRoute'])

.config(['$routeProvider', function($routeProvider) {
}])
.controller('landingCtrl', ["$scope", function($scope) {
    $scope.scrolled = false;

    $scope.$on('$routeChangeSuccess', function() {
    });
}]).
directive("scroll", ["$window", function($window){
    return {
        scope: false,
        link: function($scope, element, attrs){
            angular.element($window).bind("scroll", function(){
                if (this.pageYOffset >= 150) {
                     $scope.scrolled = true;
                     console.log($scope.scrolled + 'Scrolled 100px');
                 } else {
                     $scope.scrolled = false;
                     console.log($scope.scrolled + 'Not scrolled enough');
                 }
            });
        }
    };
}]);

这是视图代码:

<div ng-controller="landingCtrl" scroll>
    <div class="row">
        <div class="col-sm-12 col-md-9 landing-square">{{ scrolled }}</div>
        <div class="col-sm-12 col-md-3 landing-square"></div>
        ....
</div>

在视图中滚动没有定义。如果我在控制器中定义它,我可以看到它,但指令不能改变它的值。基本上我想在视图中根据指令改变值的变量“滚动”。

我错过了什么?

【问题讨论】:

  • 尝试添加 $scope.$apply() 作为滚动事件处理程序的最后一条语句,以便 Angular 获知更改。 (更好的是,将整个处理程序的内容包装在 $apply() 中。)
  • ...所有这些都假设 console.logs 确实被打印了,即事件处理程序实际上正在运行

标签: javascript angularjs angularjs-directive scope


【解决方案1】:

因为你在 Angular 不“知道”的地方(例如自定义 DOM 事件处理程序)更改范围内的某些内容,所以你需要明确告诉它应用该更改:

angular.element($window).bind("scroll", function(){
    if (this.pageYOffset >= 150) {
         $scope.$apply(function() { $scope.scrolled = true; });
         console.log($scope.scrolled + ' Scrolled 100px');
     } else {
         $scope.$apply(function() { $scope.scrolled = false; });
         console.log($scope.scrolled + ' Not scrolled enough');
     }
});

this example,见this excellent Q&A on $scope $apply and $watch。或者直接去the relevenat documentation(这是干的/技术性的,但也解释了背后的原因)。

【讨论】:

  • 文档说 $apply 用于“从角度框架外部执行角度表达式”。但是为什么我的指令应该在角度框架之外呢?
  • .bind(.... 处理程序被认为是“Angular 框架之外”的源,其中 $scope.scrolled 变量已更改。被认为在框架“内部”的典型事物是 ng-click 处理程序等。
【解决方案2】:

在指令中,您正在更改范围值。
尝试将更改应用到范围。

$scope.scrolled = true;     
$scope.$apply();

【讨论】:

    猜你喜欢
    • 2013-05-28
    • 1970-01-01
    • 2015-01-11
    • 2016-03-28
    • 1970-01-01
    • 2014-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多