AngularJS - fonksiyonu yönergelere geçirir


160

Bir örnek açısalJS var

<div ng-controller="testCtrl">

<test color1="color1" updateFn="updateFn()"></test>
</div>
 <script>
  angular.module('dr', [])
.controller("testCtrl", function($scope) {
    $scope.color1 = "color";
    $scope.updateFn = function() {
        alert('123');
    }
})
.directive('test', function() {
    return {
        restrict: 'E',
        scope: {color1: '=',
                updateFn: '&'},
        template: "<button ng-click='updateFn()'>Click</button>",
        replace: true,
        link: function(scope, elm, attrs) { 
        }
    }
});

</script>
</body>

</html>

Düğmeye tıkladığımda istiyorum, uyarı kutusu görünecek, ancak hiçbir şey görünmüyor.

Biri bana yardım edebilir mi?

Yanıtlar:


243

Bir yalıtkan kapsam yönergesi içinden üst kapsamdaki denetleyici işlevini çağırmak için dash-separated, HTML'de OP'nin belirttiği gibi öznitelik adlarını kullanın .

Ayrıca işlevinize bir parametre göndermek istiyorsanız, bir nesneyi ileterek işlevi çağırın:

<test color1="color1" update-fn="updateFn(msg)"></test>

JS

var app = angular.module('dr', []);

app.controller("testCtrl", function($scope) {
    $scope.color1 = "color";
    $scope.updateFn = function(msg) {        
        alert(msg);
    }
});

app.directive('test', function() {
    return {
        restrict: 'E',
        scope: {
            color1: '=',
            updateFn: '&'
        },
        // object is passed while making the call
        template: "<button ng-click='updateFn({msg : \"Hello World!\"})'>
            Click</button>",
        replace: true,        
        link: function(scope, elm, attrs) {             
        }
    }
});

Fiddle


1
Cevabınız için teşekkürler Codezilla ve ben "updateFn" işlevini "test" direktifinde kapsamı izole etmek için ana kapsamdan bağlamak istediğim zaman durum hakkında sormak istiyorum, bu mümkün mü?
user2707026

2
replaceNitelik angularjs önerilmemektedir olmuştur: stackoverflow.com/questions/24194972/...
cdmckay

8
nedense bu argüman benim için tanımsız.
chovy

1
@chovy Bence argüman sadece yöntemi tekrar çağırdığınızda kullanılıyor mu? İlk açık parantez kullanımı, açısal yöntemin sadece
geçilmesini

1
updateFn({msg: 'my message'});Yönerge linkişlevi içinde işlev çağrısı yapılırken bir nesne eşlemesi bu biçimde kullanılmalıdır .
Brian

159

Belki bir şey eksik, ama diğer çözümler üst kapsam işlevini çağırmak rağmen, yönerge kodundan argümanlar geçirme yeteneği yoktur, bunun nedeni, örneğin sabit parametrelerle update-fnçağırıyor . Küçük bir değişiklik, direktifin çok daha yararlı olduğunu düşündüğüm argümanları iletmesine izin verir.updateFn(){msg: "Hello World"}

<test color1="color1" update-fn="updateFn"></test>

HTML'nin bir işlev başvurusunu, yani ()köşeli ayraç olmadan geçtiğini unutmayın .

JS

var app = angular.module('dr', []);

app.controller("testCtrl", function($scope) {
    $scope.color1 = "color";
    $scope.updateFn = function(msg) {        
        alert(msg);
    }
});

app.directive('test', function() {
    return {
        restrict: 'E',
        scope: {
            color1: '=',
            updateFn: '&'
        },
        // object is passed while making the call
        template: "<button ng-click='callUpdate()'>
            Click</button>",
        replace: true,        
        link: function(scope, elm, attrs) {       
          scope.callUpdate = function() {
            scope.updateFn()("Directive Args");
          }
        }
    }
});

Dolayısıyla, yukarıda, HTML yerel kapsam callUpdateişlevini çağırıyor , bu da daha sonra updateFn'yi üst kapsamdan 'alıyor' ve döndürülen işlevi yönergelerin üretebileceği parametrelerle çağırıyor.

http://jsfiddle.net/mygknek2/


9
Nasıl bir şey için aşağı oy alabilir emin değilim ?? Oyu düşürmek için yorum bırakmalısınız.
steve

7
Bu benim için çalıştı. Ekstra fonksiyon istemiyorsanız, sadece yazınng-click="updateFn()('Directive Args')"
Graham Walters

7
Awwww! scope.updateFn () ("Yönerge Değişkenleri"); !! NOT scope.updateFn ("Yönerge Değişkenleri"); !!!
Phung D.

2
Bu gerçekten daha mükemmel bir cevap!
vinesh

11
@ Ludwik11 emin - çünkü bu şekilde tanımlandığında scope.updateFn işlevi döndüren bir işlevdir (bu nedenle () ()) ve bunun nedeni kapsama geçmemizdir (html'de update-fn = "updateFn" aracılığıyla) bir başvuru istediğimiz işleve. 1st () bu referansı döndürmek için açısal bir çağrıdır, 2nd () fonksiyonumuza çağrı yapar ve herhangi bir parametreyi geçirdiğimiz yerdir. HTH
steve

39

'Test' yönergesi Html etiketinizde, işlevin öznitelik adı camelCased değil , tire temelli olmalıdır.

yani - yerine:

<test color1="color1" updateFn="updateFn()"></test>

yazmak:

<test color1="color1" update-fn="updateFn()"></test>

Bu açısalın yönerge nitelikleri (update-fn fonksiyonu gibi) ve fonksiyonlar arasındaki farkı anlatmanın bir yoludur.


1
yakalamak için teşekkürler. Bunu cevabıma dahil ettim. Oy verildi! :)
AlwaysALearner

10

Denetleyici işlevini çift ​​yönlü ciltleme ile geçirmeye ne dersiniz ? Daha sonra yönergede normal bir şablonda olduğu gibi kullanabilirsiniz (basitlik için alakasız parçaları çıkardım):

<div ng-controller="testCtrl">

   <!-- pass the function with no arguments -->
   <test color1="color1" update-fn="updateFn"></test>
</div>

<script>
   angular.module('dr', [])
   .controller("testCtrl", function($scope) {
      $scope.updateFn = function(msg) {
         alert(msg);
      }
   })
   .directive('test', function() {
      return {
         scope: {
            updateFn: '=' // '=' bidirectional binding
         },
         template: "<button ng-click='updateFn(1337)'>Click</button>"
      }
   });
</script>

Bu soruya indim, çünkü yukarıdaki yöntemi befire denedim, ama bir şekilde işe yaramadı. Şimdi mükemmel çalışıyor.


5

özellik adı için tire ve küçük harf kullanın (diğer yanıtların söylediği gibi):

 <test color1="color1" update-fn="updateFn()"></test>

Ve yönerge kapsamında "&" yerine "=" kullanın:

 scope: { updateFn: '='}

Ardından updateFn'i diğer işlevler gibi kullanabilirsiniz:

 <button ng-click='updateFn()'>Click</button>

İşte böyle!


5
Neden '&' yerine '=' kullanıyorsunuz? bunu denediğimde tekrar tekrar benim işlev çağırma devam etti.
user1012500

2
Bunun için '=' kullanmak yanlış. Bu iki yönlü nesne bağlama içindir.
Ben Taliadoros

1
Tek sorun ilk şablonda parantez kullanılması. Bu işlevi yürütür ve sonucu bağlar. Bunun yerine, işlevin adını yalnızca şu şekilde update-fn="updateFn"
iletmelisiniz

1
Kötü cevap. çok kötü.
towry

4

Bu çalışma değildi çünkü "&" yerine "&" yerine kullanmak zorunda kaldı. Garip davranış.


2
Bunun nedeni büyük olasılıkla yönerge yürütme yerine bir JS işlev başvurusu geçirmenizdir. İşlevi yönergeye argüman olarak update-fn="updateFn()"ilettiğinizde parantez (ve belki de parametreler) eklemeniz gerekir. Bir işlev başvurusu olarak update-fn="updateFn"&
iletmek

0

@JorgeGRC Cevabınız için teşekkürler. Bir şey olsa da, "belki" kısmı çok önemlidir. Parametre (s) varsa, size şablonu o / onları yanı kapsam içine almak ve belirtmek için emin olmalıdır yerliler örn updateFn({msg: "Directive Args"}.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.