$on i $ broadcast in angular

Mam footerController i codeScannerController z różnymi widokami.

angular.module('myApp').controller('footerController', ["$scope", function($scope) {}]);

angular.module('myApp').controller('codeScannerController', ["$scope", function($scope) {
console.log("start");
$scope.startScanner = function(){...

Kiedy klikam na <li> w stopce.html powinienem pobrać to zdarzenie w codeScannerController.

<li class="button" ng-click="startScanner()">3</li>

Myślę, że można to zrealizować za pomocą $on i $broadcast, ale nie wiem jak i nigdzie nie mogę znaleźć przykładów.

Author: Gargaroz, 2013-10-18

4 answers

Jeśli chcesz $broadcast Użyj $rootScope:

$scope.startScanner = function() {

    $rootScope.$broadcast('scanner-started');
}

A następnie, aby otrzymać, użyj $scope swojego kontrolera:

$scope.$on('scanner-started', function(event, args) {

    // do what you want to do
});

Jeśli chcesz możesz przekazać argumenty kiedy $broadcast:

$rootScope.$broadcast('scanner-started', { any: {} });

A następnie otrzymać je:

$scope.$on('scanner-started', function(event, args) {

    var anyThing = args.any;
    // do what you want to do
});

Dokumentacja w Scope docs.

 591
Author: Davin Tryon,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-23 14:11:42

Po pierwsze, Krótki opis $on(), $broadcast() oraz $emit():

  • .$on(name, listener) - nasłuchuje określonego zdarzenia przez dany name
  • .$broadcast(name, args) - transmitować wydarzenie przez $scope wszystkich dzieci
  • .$emit(name, args) - emituje Zdarzenie w hierarchii {[8] } do wszystkich rodziców, w tym $rootScope

Na podstawie następującego kodu HTML (zobacz pełny przykład tutaj):

<div ng-controller="Controller1">
    <button ng-click="broadcast()">Broadcast 1</button>
    <button ng-click="emit()">Emit 1</button>
</div>

<div ng-controller="Controller2">
    <button ng-click="broadcast()">Broadcast 2</button>
    <button ng-click="emit()">Emit 2</button>
    <div ng-controller="Controller3">
        <button ng-click="broadcast()">Broadcast 3</button>
        <button ng-click="emit()">Emit 3</button>
        <br>
        <button ng-click="broadcastRoot()">Broadcast Root</button>
        <button ng-click="emitRoot()">Emit Root</button>
    </div>
</div>

Wywołane zdarzenia przejdą $scopes jako następuje:

  • Broadcast 1 - będzie widoczny tylko przez kontroler 1 $scope
  • Emit 1 - będzie widoczny przez kontroler 1 $scope wtedy $rootScope
  • Broadcast 2 - będzie widoczny przez kontroler 2 $scope następnie kontroler 3 $scope
  • Emit 2 - będzie widoczny przez kontroler 2 $scope Następnie $rootScope
  • Broadcast 3 - będzie widoczny tylko przez kontroler 3 $scope
  • Emit 3 - będzie widoczny przez kontroler 3 $scope, Kontroler 2 $scope Następnie $rootScope
  • Broadcast Root-Will być widziane przez $rootScope i $scope wszystkich kontrolerów (1, 2, 3)
  • Emit Root - będzie widoczny tylko przez $rootScope

JavaScript, aby wyzwalać zdarzenia (ponownie możesz zobaczyć działający przykład tutaj):

app.controller('Controller1', ['$scope', '$rootScope', function($scope, $rootScope){
    $scope.broadcastAndEmit = function(){
        // This will be seen by Controller 1 $scope and all children $scopes 
        $scope.$broadcast('eventX', {data: '$scope.broadcast'});

        // Because this event is fired as an emit (goes up) on the $rootScope,
        // only the $rootScope will see it
        $rootScope.$emit('eventX', {data: '$rootScope.emit'});
    };
    $scope.emit = function(){
        // Controller 1 $scope, and all parent $scopes (including $rootScope) 
        // will see this event
        $scope.$emit('eventX', {data: '$scope.emit'});
    };

    $scope.$on('eventX', function(ev, args){
        console.log('eventX found on Controller1 $scope');
    });
    $rootScope.$on('eventX', function(ev, args){
        console.log('eventX found on $rootScope');
    });
}]);
 84
Author: th3uiguy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-06-24 09:51:48

Należy wiedzieć, że prefix $ odnosi się do metody kątowej, prefix $$ odnosi się do metod kątowych, których należy unikać.

Poniżej znajduje się przykładowy szablon i jego Kontrolery, zbadamy, w jaki sposób $broadcast/$on może pomóc nam osiągnąć to, czego chcemy.

<div ng-controller="FirstCtrl">
    <input ng-model="name"/> 
    <button ng-click="register()">Register </button>
</div>

<div ng-controller="SecondCtrl">
    Registered Name: <input ng-model="name"/> 
</div>

Kontrolerami są

app.controller('FirstCtrl', function($scope){
    $scope.register = function(){

    }
});

app.controller('SecondCtrl', function($scope){

});

Moje pytanie do ciebie brzmi jak przekazać nazwę do drugiego kontrolera, gdy użytkownik kliknie zarejestruj? Możesz wymyślić wiele rozwiązań, ale tego, którego użyjemy używa $broadcast i $on.

$broadcast vs $emit

Czego powinniśmy użyć? $broadcast skieruje się w dół do wszystkich potomnych elementów dom, a $emit skieruje się w przeciwnym kierunku do wszystkich przodkowych elementów dom.

Najlepszym sposobem na uniknięcie decyzji pomiędzy $emit lub $broadcast jest kanał z $ rootScope i używanie $ broadcast do wszystkich jego dzieci. Co znacznie ułatwia sprawę, ponieważ nasze elementy dom są rodzeństwem.

Dodawanie $rootScope and lets $broadcast

app.controller('FirstCtrl', function($rootScope, $scope){
    $scope.register = function(){
        $rootScope.$broadcast('BOOM!', $scope.name)
    }
});

Uwaga dodaliśmy $rootScope i teraz używamy $broadcast (broadcastName, arguments). Dla broadcastName, chcemy nadać mu unikalną nazwę, abyśmy mogli złapać tę nazwę w naszym secondCtrl. Wybrałem BOOM! dla Zabawy. Drugi argument 'arguments' pozwala nam przekazywać wartości do słuchaczy.

Odbieranie naszej transmisji

W naszym drugim kontrolerze musimy ustawić kod do odsłuchu naszej transmisji

app.controller('SecondCtrl', function($scope){
  $scope.$on('BOOM!', function(events, args){
    console.log(args);
    $scope.name = args; //now we've registered!
  })
});
To naprawdę to proste. Przykład Na Żywo

Inne sposoby osiągnięcia podobnych wyników

Staraj się unikać używania tego zestawu metod, ponieważ nie jest ani wydajny, ani łatwy w utrzymaniu, ale jest to prosty sposób na naprawienie problemów, które możesz mieć.

Zazwyczaj możesz zrobić to samo, korzystając z usługi lub upraszczając Kontrolery. Nie będziemy omawiać tego szczegółowo, ale pomyślałem, że wspomnę o tym dla kompletności.

Na koniec należy pamiętać o naprawdę użytecznej transmisji do listen to jest '$ destroy ' ponownie widać $ oznacza, że jest to metoda lub obiekt utworzony przez kody dostawcy. Tak czy inaczej $destroy jest nadawany, gdy kontroler zostanie zniszczony, możesz posłuchać tego, aby wiedzieć, kiedy kontroler zostanie usunięty.

 26
Author: Yang Li,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-03-01 23:58:19
//Your broadcast in service

(function () { 
    angular.module('appModule').factory('AppService', function ($rootScope, $timeout) {

    function refreshData() {  
        $timeout(function() {         
            $rootScope.$broadcast('refreshData');
        }, 0, true);      
    }

    return {           
        RefreshData: refreshData
    };
}); }());

//Controller Implementation
 (function () {
    angular.module('appModule').controller('AppController', function ($rootScope, $scope, $timeout, AppService) {            

       //Removes Listeners before adding them 
       //This line will solve the problem for multiple broadcast call                             
       $scope.$$listeners['refreshData'] = [];

       $scope.$on('refreshData', function() {                                                    
          $scope.showData();             
       });

       $scope.onSaveDataComplete = function() { 
         AppService.RefreshData();
       };
    }); }());
 1
Author: Sandy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-13 21:06:46