2016-05-23 124 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();