2013-02-12 17 views
19

Bazı işlevleri yerel kapsamına $scope.$on ile bağlayan bir yönergem var.

Aynı işlevi tek bir çağrıda birden çok olaya bağlamak mümkün mü?

app.directive('multipleSadness', function() { 
    return { 
     restrict: 'C', 
     link: function(scope, elem, attrs) { 
      scope.$on('event:auth-loginRequired event:auth-loginSuccessful', function() { 
       console.log('The Ferrari is to a Mini what AngularJS is to ... other JavaScript frameworks'); 
      }); 
     } 
    }; 
}); 

Ama bu işe yaramazsa:

İdeal böyle bir şey yapmak mümkün olurdu. Aynı örnek, ['event:auth-loginRequired', 'event:auth-loginConfirmed'] ile değiştirilen virgülle ayrılmış olay adı dizesiyle de yazılmaz.

app.directive('multipleSadness', function() { 
    return { 
     restrict: 'C', 
     link: function(scope, elem, attrs) { 

      scope.$on('event:auth-loginRequired', function() { 
       console.log('The Ferrari is to a Mini what AngularJS is to ... other JavaScript frameworks'); 
      }); 
      scope.$on('event:auth-loginConfirmed', function() { 
       console.log('The Ferrari is to a Mini what AngularJS is to ... other JavaScript frameworks'); 
      }); 
     } 
    }; 
}); 

Ama bu ideal değildir:

Ne çalışır budur.

Tek seferde aynı işlevi birden çok olaya bağlamak mümkün mü?

cevap

11

Evet. Bunun gibi:

app.directive('multipleSadness', function() { 
    return { 
     restrict: 'C', 
     link: function(scope, elem, attrs) { 

      function sameFunction(eventId) { 
       console.log('Event: ' + eventId + '. The Ferrari is to a Mini what AngularJS is to ... other JavaScript frameworks.'); 
      } 

      scope.$on('event:auth-loginRequired', function() {sameFunction('auth-loginRequired');}); 
      scope.$on('event:auth-loginConfirmed', function() {sameFunction('auth-loginConfirmed');}); 
     } 
    }; 
}); 

Ama sadece yapabildiğiniz için, yapmanız gerektiği anlamına gelmez :). Olaylar başka bir dinleyiciye kadar yayılmaya devam ederse ve orada farklı şekilde ele alınırsa, belki bunu yapmak için bir durum söz konusudur. Eğer bu sadece tek bir dinleyici olacaksa, sadece aynı olayı yaymanız (veya yayınlamanız) gerekir.

+0

Etkinlik yayılımı ve etkinlik kimliği ile ilgili ek bilgiler için teşekkürler, bunu bildiğim için neden sorduğumun nedeni doğal olarak mümkün değildir. Olaylar farklı dinleyicilere sahip, ancak bu dinleyicinin aynı eylemi birden fazla olayda gerçekleştirmesi gerekiyor. –

+0

Gözden geçirmemden sonra kodumun daha fazla olmasını sağladım * Açısal *. Halen iki olay var, ama farklı şeyleri (refactoring) ifade ettikleri için, ikisini de aynı işleve bağlamak için bir sebep yok. İşaretçiler için teşekkürler. –

+0

Hiç sorun değil. Yardımcı olduğuma sevindim. – testing123

7

Bu durumun mümkün olabileceğini sanmıyorum, çünkü olay geri bildirime veri gönderiyor olabilir ve birden fazla etkinlik dinlerseniz hangi verilerin hangi etkinlikten geldiğini bilmezsiniz. Böyle bir şey yapardı

:

function listener() { 
    console.log('event fired'); 
} 
scope.$on('event:auth-loginRequired', listener); 
scope.$on('event:auth-loginConfirmed', listener); 
13

angularjs bağlayıcı birden olayı desteklemez ama böyle bir şey yapabilirsiniz:

var handler = function() { ... } 
angular.forEach("event:auth-loginRequired event:auth-loginConfirmed".split(" "), function (event) { 
    scope.$on(event, handler); 
}); 
+1

"Olay: auth-loginRequired olayı: auth-loginConfirmed" .split ("") yerine sadece ['event: auth-loginRequired', 'event: auth-loginConfirmed'] yerine kullanmanın bir nedeni var mı? –

+0

@ RyanO'Neill Özel bir neden yok =) ['', '', '', ...] 'ye sahip olmaktan çok tek bir dizeye sahip olmak daha temiz görünüyor. Ayrıca OP'nin örneği, virgülle ayrılmış tek bir dizgeydi. – bmleite

+2

Teşekkürler. JavaScript ne olduğu hakkında, bilmem gereken bir Wat anını kaçırmadığımdan emin olmak istedim. –

27

diğer cevaplar (Anders Ekdahl)

her zaman senin rulo olabilir, o Barring ... Doğru% 100 ... onlardan biri ... AMA seçersin kendi:

// a hack to extend the $rootScope 
app.run(function($rootScope) { 
    $rootScope.$onMany = function(events, fn) { 
     for(var i = 0; i < events.length; i++) { 
     this.$on(events[i], fn); 
     } 
    } 
}); 

app.directive('multipleSadness', function() { 
    return { 
     restrict: 'C', 
     link: function(scope, elem, attrs) { 
      scope.$onMany(['event:auth-loginRequired', 'event:auth-loginSuccessful'], function() { 
       console.log('The Ferrari is to a Mini what AngularJS is to ... other JavaScript frameworks'); 
      }); 
     } 
    }; 
}); 

.split(',')'u gerçekten yapmak isteseydiniz, ancak bu bir uygulama detayıdır. .

+1

Bunu kullanabilmeniz için bunu PR olarak göndermelisiniz. Belki de sadece kredi alacağım. –

+1

Her yinelemede uzunluğun kontrol edilmesi çok pahalıdır; uzunluğu –

+7

@ VerdiErelErgün "çok pahalı" değişkenine atamak daha mı iyi? Vurmak için ms başına kaç kez bunu tahmin ediyorsunuz? Bazı bağlamaları kurmak için tek seferlik bir çağrı. Mikro optimizasyon burada gerçekten bir nokta değildi ... Ama evet, biri için (var i = 0, len = events.length; i

1

Ayrıca yöntemi $ uzatmak mümkün $ rootScope $ onMany (@ ben-Lesh çözelti) ile mi:

var $onOrigin = $rootScope.$on; 

$rootScope.$on = function(names, listener) { 
    var self = this; 

    if (!angular.isArray(names)) { 
    names = [names]; 
    } 

    names.forEach(function(name) { 
    $onOrigin.call(self, name, listener); 
    }); 

}; 

here aldı.

+1

, çocuk kapsamlarının değiştirilmiş işlevi de devralmasını istiyorsanız, '$ rootScope .__ proto __. $ On' (veya '$ rootScope.constructor.prototype. $ On') öğesini değiştirmelisiniz. – cipak

İlgili konular