2012-12-20 24 views
27

Yani ben ul olay bağlamak ve jquery ne yaptığının li en çeşidiyle temsilci için bir yol, her li 100 li en olmalıdır ng-tıklama ile bir ul varsa veya varsa ? Bu daha mı yoksa daha mı kötü olur? 100 olay mı yaşıyoruz yoksa sonunda sadece bir olay mı?Açısal ng-tıklama etkinlik heyeti

+0

bir arkadaşım bu işaret: Mümkünse http://plnkr.co/edit/uC49BsKmvvDvQNJ72r0v?p=preview uçakla bu achiev için açısal – Vengarioth

cevap

21

Açısal, tekrarlayıcılarla olay temsilcisi yapmaz gibi görünüyor. Birisi issue on github about it'u açtı. Tartışma aslında daha iyi bir performansa yol açıyorsa.

bir çözümü vardır olabilir ama jQuery gerektirecektir. Bir ana eleman üzerinde kullanılacak özel bir direktif oluşturmaktan ve dinleyiciyi dom düğümünde kaydetmekten oluşur.

İşte o çocuk düğüm tıklandığında çağrılacak bir işlev adı geçirilir ve ayrıca dinlemek için hangi çocuk düğümleri belirlemesine yardımcı olacak bir seçici geçirilir, bir örnek. Köşenin jQuery uygulaması yalnızca bind yöntemini verdiğinden, olay dinleyicilerini gerçek öğeye kaydetmekle sınırlı - jQuery'yi on veya delegate yöntemine erişmek için yüklememiz gerekir.

HTML

<ul click-children='fun' selector='li'> 
    <li ng-repeat="s in ss" data-index="{{$index}}">{{s}}</li> 
</ul> 

tanımlı fonksiyon denetleyicisi tanımlanır ve yönerge adı verilecek bir fonksiyonu haline bir ifade dönüştürmek için $parse kullanır

$scope.fun = function(index){ 
    console.log('hi from controller', index, $scope.ss[index]);  
}; 

bir indeksi geçirilmesini bekliyor olay dinleyicisinden.

app.directive('clickChildren', function($parse){ 
    return { 
    restrict: 'A', 
    link: function(scope, element, attrs){  
     var selector = attrs.selector; 
     var fun = $parse(attrs.clickChildren); 
     element.on('click', selector, function(e){  
     // no need to create a jQuery object to get the attribute 
     var idx = e.target.getAttribute('data-index');   
     fun(scope)(idx);   
     }); 
    } 
    }; 
}); 

Plunker: http://plnkr.co/edit/yWCLvRSLCeshuw4j58JV?p=preview


Not: Fonksiyonlar bir göz değer olan izolat kapsamları {fun: '&'} kullanarak direktifleri devredilebilir, ancak bu karmaşıklığı artar. Burada JM-en örneğinin kapalı çalışma

+0

Hey sen için çok jm- teşekkür ediyoruz Cevap. Eğer bu daha çok çekici olursa olsun her zaman merak ettim. Bazı js perfs koşmak için gitmek gitmek zaman farkı fark edebilirim. Bu çözüm oldukça havalı! – climboid

+1

Ayrıca, olay dinleyicisini 'element'den kaldırmak için' $ destroy' olayını da dinlemek istersiniz. Aksi halde, öğe DOM'dan kaldırıldığında bir bellek sızıntısı olduğuna inanıyorum. – Greg

+0

"e.target" yerine "e.currentTarget" işlevini kullanmanız gerekiyor. 'e.target' öğesi tıklama altındadır. "e.currentTarget", etkinliğin eklendiği öğedir (hatta temsil edilen etkinlik). Örneğin, html ' ' metninde 'ise ve temsilci seçici 'a' ise' e.target' 'span' öğesi olur ve 'e.currentTarget'' a' öğesi olur. – djxak

6

, bu direktifin daha özlü ve esnek sürümünü yazdı. Paylaşacağımı düşündüm. Kredi, jm'ye geçer;)

Sürümüm, işlev adını $ scope [fn] (e, data) olarak çağırmayı dener veya incelikle başarısız olur.

Tıklanan öğeden isteğe bağlı bir json nesnesini geçirir. Bu, Açısal ifadeleri kullanmanıza ve çağrılan yönteme çok sayıda özellik aktarmanıza olanak tanır.

HTML

<ul delegate-clicks="handleMenu" delegate-selector="a"> 
    <li ng-repeat="link in links"> 
    <a href="#" data-ng-json='{ "linkId": {{link.id}} }'>{{link.title}}</a> 
    </li> 
</ul> 

JavaScript

Kontrolör Yöntem

$scope.handleMenu = function($event, data) { 
    $event.preventDefault(); 
    $scope.activeLinkId = data.linkId; 
    console.log('handleMenu', data, $scope); 
} 

Direktifi Oluşturucu

// The delegateClicks directive delegates click events to the selector provided in the delegate-selector attribute. 
// It will try to call the function provided in the delegate-clicks attribute. 
// Optionally, the target element can assign a data-ng-json attribute which represents a json object to pass into the function being called. 
// Example json attribute: <li data-ng-json='{"key":"{{scopeValue}}" }'></li> 
// Use case: Delegate click events within ng-repeater directives. 

app.directive('delegateClicks', function(){ 
    return function($scope, element, attrs) { 
    var fn = attrs.delegateClicks; 
    element.on('click', attrs.delegateSelector, function(e){ 
     var data = angular.fromJson(angular.element(e.target).data('ngJson') || undefined); 
     if(typeof $scope[ fn ] == "function") $scope[ fn ](e, data); 
    }); 
    }; 
}); 
Herkes katkıda bulunmak isterse geribildirim duymak isteriz

.

Bunu daha karmaşık bir uygulamadan ayıkladığımdan, handleMenu yöntemini test etmedim.

+0

Nice çalışma keşfetmek onun değer emin değilim. "Nesnenin bir değerini almak için nesne nokta gösterimini ayrıştır" seçeneğine georg cevabının bir uyarlamasını kullanarak geliştirmem görün. – BillVo

0

Yukarıdaki BradGreens 'delegateClicks' den başlayarak, handleMenu işlevini $ kapsamına (örn. $ Scope.tomato.handleMenu) yerleştirmeme izin veren some code from georg'u uyarladım.

app.directive('delegateClicks', function() { 
    return function ($scope, element, attrs) { 
     var fn = attrs.delegateClicks.split('.').reduce(function ($scope, p) { return $scope[p] }, $scope); 
     element.on('click', attrs.delegateSelector, function (e) { 
      var data = angular.fromJson(angular.element(e.target).data('ngJson') || undefined); 
      if (typeof fn == "function") fn(e, data); 
     }); 
    }; 
});