2013-03-01 22 views
35

Denetleyici işlevinde bir yönerge özniteliklerine erişmeye çalışıyorum. Ancak, eriştiğim zaman, tanımsızdır. Basit bir zamanlayıcı yaparsam işe yaradığını fark ettim. Sadece direktifin ardından kodun yürütülmesi için bir yol var mı ve kapsamları hazır ve kullanılmaya hazır mı?AngularJS yönergeleri, denetleyiciden erişimi denetler

Onunla bir keman yaptım. Konsolunuzun açık olduğundan emin olun. İşte

http://jsfiddle.net/paulocoelho/uKA2L/1/ ben keman içinde kullanıyorum kodu:

<div ng-app="testApp" > 
    <testcomponent text="hello!"></testcomponent> 
</div> 
Eğer bağlama ve denetleyici işlevleri içinde

scope.text = $attrs.text; 

ayarlarsanız, işleri ne

var module = angular.module('testApp', []) 
    .directive('testcomponent', function() { 
    return { 
     restrict: 'E', 
     template: '<div><p>{{text}} This will run fine! </p></div>', 
     scope: { 
      text: '@text' 
     }, 
     controller: function ($scope, $element) { 
      console.log($scope.text); // this will return undefined 
      setTimeout(function() { 
       console.log($scope.text); // this will return the actual value... 
      }, 1000); 
     }, 
     link: function ($scope, $element, $attrs) { 
      console.log($scope.text); 
      setTimeout(function() { 
       console.log($scope.text); 
      }, 1000); 
     } 
    }; 
}); 

cevap

25

. Bu sadece başlangıçta çalışmayacaktır, çünkü 2 yönlü veritabanında yoktur. Ancak $attrs.observe'u kullanabilirsiniz.

bakınız keman: o an kapsam değişkenleri tanımsız olan en http://jsfiddle.net/JohannesJo/nm3FL/2/

+0

yup, benim için çalışıyor :) teşekkürler adam – PCoelho

+1

Bu tiftiklenmesinin başarısız olur. 'attrs.text' olarak bilinmemektedir. –

+1

@DougChamberlain Bunu yapmak için JSDoc'u kullanabilirsiniz. @param {string} attrs.text' gibi bir şey sorununuzu çözmelidir. –

1

bağlantı fonksiyonu, döngü sindirmek $ önce denir. Bağlantı işlevinin nasıl çalıştığını anlamak için this chapter ve this other'a bakın. Modelin manipüle edilmemesi için direktifin saatlerini ve/veya davranışlarını tanımlamak için sadece bağlantı fonksiyonunu kullanırsınız, bu kontrolörlerde yapılır.

+0

Bu hepsi doğru değil. Kapsam değişkenleri, post-link işlevinin çalıştırıldığı süreye göre tanımlanır ve veri modelinizi bir link işlevinde işlemek iyi olur. Denetleyicileri, yalnızca bir yönerge üzerinde, gereksinim özelliği aracılığıyla başka bir yönerge ile iletişim kurmak için kullanmayı planlıyorsanız, yalnızca bir yönergede gerekir. Kontrolör aslında önce çalışır, ardından ön bağlantı, dom ağacından aşağıya doğru yapraklara gider, sonra kök kaynağına post-link yapar. Açıklama için bu konuya bakın. https://stackoverflow.com/questions/24615103/angular-directives-when-and-how-to-use-compile-controller-pre-link-and-post –

23

Yalıtılmış bir kapsamda, bağlantı işlevinde '@' ile tanımlanan yerel kapsam özelliğine erişilemez. @remigio'nun daha önce bahsettiği gibi, buradaki yerel kapsam özellikleri bu noktada undefined'dur. $ attrs. $ observe() veya $ scope. $(), (interpolasyonlu) değeri eşzamansız olarak elde etmek için kullanılmalıdır.

Öznitelikte sabit bir değer iletiyorsanız, (yani, enterpolasyon gerekmez, ör. Öznitelik değeri herhangi bir {{}} s içermiyorsa) '@' veya $ gözlemciye gerek yoktur. $ izle. $ Attrs kullanabilirsiniz. attribute_name bir kez @hugo'nun önerdiği gibi, veya bir sayı veya bir boole geçiriyorsanız ve doğru tür almak istiyorsanız, bir defa $ scope. $ Eval ($ attrs. öznitelik_adi) kullanabilirsiniz.

Yerel etki alanı özelliğini bir ana kapsam özelliğine iliştirmek için '=' öğesini kullanırsanız, özelliğin değeri bağlantı işlevinde ($ gözlem veya $ watch veya $ eval gerekmeden) kullanılabilir.

+0

+1 Bu beni deli ediyordu. – GFoley83

+0

+1 Açıklama için teşekkürler! –

0

Bir yönergesini kullanarak görünümünde ekleyecek şekilde direktifi bu değeri erişen Eğer $ derleme API kullanarak ve Açısal 1.3 beri bu

var string = "<div> " + scope.text + "</div>"; 
$compile(string)(scope, function(cloned, scope){ 
     element.append(cloned); 
}); 
7

böyle bir şey yaptığını bu niteliği erişebilir, kullanabilirsiniz bindToController. İşte onu nasıl kullandığımın bir örneği. İşte, kapsamına niteliği ekleyin ve sonra denetleyici içinde ki kullanmak bindToController kullanın:

var module = angular.module('testApp', []) 
    .directive('testcomponent', function() { 
    return { 
     restrict: 'E', 
     template: '<div><p>{{text}} This will run fine! </p></div>', 
     scope: { 
      text: '@text' 
     }, 
     controller: function() { 
      console.log(this.text); 
     }, 
     controllerAs: 'vm', 
     bindToController: true 
    }; 
}); 

Eğik 1.3 yazdığını yapar bindToController denilen direktif tanımı nesne, yeni bir özellik tanıttı. ControllerAs, 'u kullanan izole bir kapsamda bir direktifte true değerine ayarlandığında, bileşenin özellikleri, kapsamın yerine denetleyiciye bağlanır.Yani, Angular, denetleyicinin örneği olduğunda, yalıtılmış kapsam bağlarının başlangıç ​​değerlerinin olduğunu ve gelecekteki değişikliklerin de otomatik olarak kullanılabilir olduğundan emin olmasını sağlar. Bunun yerine yönergesi almak için $scope kullanılarak

+1

Bu benim için çalışmadı, this.text undefined. – rjh

+0

@rjh Yönergeyi böyle çağırırken "metni" ilettiniz mi? Neel

5

şahsen ben link fonksiyonunun 3 parametrede de controller fonksiyonu için $attrs veya sadece attrs kullanmayı tercih değerini bağlıyor. Ben aşımsız kodu izleyerek bir controller gelen nitelikler değeri olsun sorunum yok:

var module = angular.module('testApp', []) 
    .directive('testcomponent', function() { 
    return { 
    restrict: 'E', 
    template: '<div><p>{{text}} This will run fine! </p></div>', 
    scope: { 
     text: '@text' 
    }, 
    controller: ['$scope','$attrs', function ($scope, $attrs) { 
     console.log($attrs.text); // just call to the $attrs instead $scope and i got the actual value 
     $scope.text = $attrs.text; //assign attribute to the scope 
    }] 
    }; 
}); 
İlgili konular