SORU
28 HAZİRAN 2012, PERŞEMBE


Ne'In AngularJS?denetleyicileri arasında iletişim kurmak için doğru yolu

AngularJS denetleyicileri arasında iletişim kurmak için doğru yolu nedir?

Şu anda korkunç bir şekerleme içeren kullanıyorum '': . pencere

function StockSubgroupCtrl($scope, $http) {
    $scope.subgroups = [];
    $scope.handleSubgroupsLoaded = function(data, status) {
        $scope.subgroups = data;
    }
    $scope.fetch = function(prod_grp) {
        $http.get('/api/stock/groups/'   prod_grp   '/subgroups/').success($scope.handleSubgroupsLoaded);
    }
    window.fetchStockSubgroups = $scope.fetch;
}

function StockGroupCtrl($scope, $http) {
    ...
    $scope.select = function(prod_grp) {
        $scope.selectedGroup = prod_grp;
        window.fetchStockSubgroups(prod_grp);
    }
}

CEVAP
21 EKİM 2013, PAZARTESİ


Edit: Bu sorunun cevabını ele *5 angular.js * şimdi kayıtsız kapsamları üzerinde fokurdayan önler ve aynı hızda $yayan olarak çalışır son sürümlerinde giderilmiştir.

$broadcast performances are identical to $emit with angular 1.2.16


Aşağıda Orijinal Cevap

Ben çok 6* $scope.$on *daha ziyade 8* $rootScope.$on*kullanmak için değil tavsiye. Eski @numan yetiştirdiği gibi ciddi performans sorunlarına neden olabilir. Bu olay aşağı aracılığıyla bubble olmasıdırtümkapsamları.

Ancak, ikincisi ($rootScope.$emit $rootScope.$onkullanarak) yapardeğilbu muzdarip ve bu nedenle hızlı bir iletişim kanalı olarak kullanılabilir!

$emit Dokümantasyon: açısal

Bir etkinlik kapsamında hiyerarşi kayıtlı bildiren üzerinden Yukarı adı gönderir

$rootScope, yukarıda kapsamı yoktur, çünkü hiçbir köpürme oluyor. Tamamen güvenli bir EventBus olarak 14*/ $rootScope.$on() *kullanmaktır.

Ancak, Kontrolörler içinde kullanırken bir tane yakaladım. Doğrudan bir denetleyici içinden $rootScope.$on() bağlama, $scope yerel yok olmaya başladığında, kendine bağlama temizlemek gerekecek. Bu denetleyicileri (hizmetler aksine) bağlamaları sonunda bellek sızıntıları oluşturmak her yerde toparlayarak içine yol açacak bir uygulamanın ömrü boyunca birden çok kez:) örneği alabilir çünkü

Kaydını silmek için, $scope'$destroy olay ın ardından $rootScope.$on tarafından döndürülen işlev çağrısı. senin dinle

angular
    .module('MyApp')
    .controller('MyController', ['$scope', '$rootScope', function MyController($scope, $rootScope) {

            var unbind = $rootScope.$on('someComponent.someCrazyEvent', function(){
                console.log('foo');
            });

            $scope.$on('$destroy', unbind);
        }
    ]);

Kaynakları temizlemek için, diğer EventBus uygulamaları için de geçerlidir açısal olarak gerçekten özel bir şey değil derdim.

Ancak, senolabilirhayatını bu durumlar için daha kolay hale getirmek. Örneğin, sen-ebil maymun yama $rootScope göster kendini $onRootScope abone olduğu için olayları yayılan on $rootScope ama aynı zamanda doğrudan temizler işleyicisi zaman yerel $scope alır yok.

En temiz şekilde maymun yama $rootScope sağlamak $onRootScope yöntem olurdu ile bir dekoratör (run engeller muhtemelen yeter de ama haberiniz olsun, kimseye söyleme)

$onRootScope özelliği $scope Object.defineProperty() kullandığımız numaralandırma sırasında beklenmeyen görünmediğinden emin olun ve false enumerable ayarlayın. ES5 bir dolgu gerekebilir unutmayın.

angular
    .module('MyApp')
    .config(['$provide', function($provide){
        $provide.decorator('$rootScope', ['$delegate', function($delegate){

            Object.defineProperty($delegate.constructor.prototype, '$onRootScope', {
                value: function(name, listener){
                    var unsubscribe = $delegate.$on(name, listener);
                    this.$on('$destroy', unsubscribe);

                    return unsubscribe;
                },
                enumerable: false
            });


            return $delegate;
        }]);
    }]);

Bu yöntem ile yukarıdan kumanda kodu için basitleştirilmiş olabilir:

angular
    .module('MyApp')
    .controller('MyController', ['$scope', function MyController($scope) {

            $scope.$onRootScope('someComponent.someCrazyEvent', function(){
                console.log('foo');
            });
        }
    ]);

Yani tüm bu nihai bir sonuç olarak ben çok$rootScope.$emit $scope.$onRootScopekullanmanızı tavsiye.

Btw, açısal çekirdek içinde sorunu çözmek için açısal ekibi ikna etmeye çalışıyorum. Bir tartışma oluyor: https://github.com/angular/angular.js/issues/4574

Burada $broadcast100 $scopesadece's. iyi bir senaryoda masaya getiriyor gösteren bir jsperf.

http://jsperf.com/rootscope-emit-vs-rootscope-broadcast

jsperf results

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Damian Winter

    Damian Winte

    27 ŞUBAT 2007
  • DavideoDesign

    DavideoDesig

    24 NİSAN 2006
  • The Slow Mo Guys

    The Slow Mo

    15 AĞUSTOS 2010