2016-05-23 6 views
2

Ich verwende eine Direktive, um zu überprüfen, wie viel der Benutzer das Fenster scrollt, aber ich kann nicht das Scope mit dem Controller binden.Binding directory scope mit Controller in AngularJS

Hier ist die Richtlinie und Controller-Code:

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

dies ist der Ansicht Code:

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

Nach Ansicht nicht definiert gescrollt wird. Wenn ich es im Controller definiere, kann ich es sehen, aber die Direktive kann ihren Wert nicht ändern. Grundsätzlich möchte ich in der Ansicht die Variable "scrollen", die den Wert gemäß der Richtlinie ändert.

Was fehlt mir?

+0

Versuchen Sie $ $ scope. $ Apply() 'als letzte Anweisung des Scroll Event Handlers hinzuzufügen, so dass Angular über die Änderung informiert wird. (Besser noch, wickle den Inhalt des gesamten Handlers in '$ apply()'.) –

+0

... all das vorausgesetzt, die console.logs werden gedruckt, dh der Event-Handler läuft tatsächlich –

Antwort

0

Weil Sie ändern ein etwas über den Umfang an einem Ort Angular nicht „wissen“ (zB einen benutzerdefinierter DOM Event-Handler), müssen Sie es ausdrücklich sagen, dass die Änderung zu übernehmen:

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

Siehe this example und siehe this excellent Q&A on $scope$apply and $watch. Oder gehen Sie einfach direkt zu the relevenat documentation (was trocken/technisch ist, aber erklärt die Begründung dahinter).

+0

Die Dokumentation besagt, dass $ apply ist verwendet, um "einen Ausdruck im Winkel von außerhalb des Winkelgerüsts auszuführen". Aber warum sollte meine Richtlinie außerhalb des kantigen Rahmens sein? – ste

+0

Der '.bind (....' Handler wird als eine Quelle "außerhalb des Angular-Frameworks" betrachtet, bei der die Variable '$ scope.scrolled' geändert wird. Typische Dinge, die innerhalb des Frameworks liegen, sind' ng -Klicken Sie 'Handler und so weiter. – Jeroen

0

In der Direktive ändern Sie die Bereichswerte.
Versuchen Sie, die Änderungen auf den Bereich anzuwenden.

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