2016-05-23 76 views
2

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

这里的指令和控制器代码:

'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> 

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

我错过了什么?

+0

尝试添加'$ scope。$ apply()'作为滚动事件处理程序的最后一条语句,以便Angular获知有关更改的信息。 (更好的是,将整个处理程序的内容包装在'$ apply()'中。) –

+0

...所有这些都假定console.logs是打印的,即事件处理程序实际上正在运行 –

回答

0

因为你改变的地方角不“知道”(如自定义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(这是干的/技术性的,但也解释了它背后的推理)。

+0

文档说$ apply用于“从角框架外部以角度执行表达式”。但为什么我的指令应该超出角度框架? – ste

+0

'.bind(....'处理程序被认为是“Angular框架之外的一个源”,其中'$ scope.scrolled'变量被改变,被认为是框架内部的典型事物是'ng点击“处理程序等。 – Jeroen

0

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

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