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.