Açısal2 - Şablonda özel değişkenlere erişilebilir olmalı mı?


143

Bir değişken privatebir bileşen sınıfında bildirilirse , o bileşenin şablonundan ona erişebilmeli miyim?

@Component({
  selector: 'my-app',
  template: `
    <div>
      <h2>{{title}}</h2>
      <h2>Hello {{userName}}</h2> // I am getting this name
    </div>
  `,
})
export class App {
  public title = 'Angular 2';
  private userName = "Test Name"; //declared as private
}

Yanıtlar:


226

Hayır, şablonlarınızda özel değişkenler kullanmamalısınız.

Ben drewmoore'un cevabını beğenip mükemmel kavramsal mantığı görsem de, uygulama yanlıştır. Şablonlar bileşen sınıflarında değil, bunların dışında bulunur. Kanıt için bu repoya bir göz atın .

Çalışmasının tek nedeni, TypeScript'in privateanahtar kelimesinin gerçekten üyeyi özel yapmamasıdır. Tam zamanında derleme, çalışma zamanında bir tarayıcıda gerçekleşir ve JS'nin henüz özel üye kavramı yoktur (henüz?). Kredi beni doğru yola soktuğu için Sander Elias'a gidiyor .

Önceden ngcve Derleme derlemesinde, bileşenin özel üyelerine şablondan erişmeyi denerseniz hata alırsınız. Gösteri deposunu klonlayın, MyComponentüyelerin görünürlüğünü özel olarak değiştirin ve çalışırken derleme hataları alırsınız ngc. Burada ayrıca Zamanın Önde Derlemesi için özel bir cevap bulunmaktadır .


6
bu en iyi yorum ve imo kabul edilen cevap olmalı. Özel değişkenleri aktarıldıktan sonra kullanabileceğinizden değil, yapmanız gereken .. Kodu temiz tutun!
Sam Vloeberghs

2
Bu geçerli tek cevap! Codelyzer artık şablonunuzda özel değişken kullandığınızda sizi uyarıyor.
maxime1992

7
Bununla ilgili tek sorunum, @Inputs ve Outputs gibi halka açık gerçek üyeler arasında dış dünyaya değil, sadece şablonumuza göstermek istediğimiz üyelere nasıl ayrım yapıyorsunuz. Yöntem / üyelerin şablona erişebilmesini ancak diğer bileşenlerin erişmesini istemediğiniz yerlerde yeniden kullanılabilir bileşenler oluşturuyorsanız. Bence orijinal cevap doğru. Şablonlar bileşenin bir parçasıdır.
Ashg

1
@Ashg - sadece wrt Girişler ve Çıkışlar ile aynı fikirde değilim. Bileşenler arasında iletişim kurmak istediğimde ne olur , örneğin alt bileşenine bir üst bileşen enjekte ederek. Alt bileşen daha sonra , yalnızca üst öğenin dış dünyaya göstermek istediği yöntemler yerine üst öğenin şablonuna açıkladığı her şeyi görebilir . Angular kısıtlamaları dahilinde, bu cevap doğru cevap olmaya devam ediyor, ancak bu tasarımın iyi düşünülmüş olduğunu sanmıyorum.
Dan King

Bu, Angular'ın AoT derlemesindeki sınırlamaları ve bunların etrafından nasıl geçileceğini ele aldığı için iyi bir cevaptır. Ancak, IMO sorusu kavramsal idi (kasıtlı olarak ya da değil). Kavramsal olarak, şablonlar sınıf tanımlarının bir parçasıdır. Şablonlar sınıfları genişletmez veya miras almaz ve dışarıdan başlatılan nesnelere erişmezler ... bunun tersi de geçerlidir. Şablonlar sınıfın içinde tanımlanır, bu nedenle kavramsal olarak sınıfın bir parçasıdır ve kavramsal olarak özel üyelere erişebilmelidir.
A-Diddy

85

Düzenleme: Bu yanıt şimdi yanlış. Bu konuyu yayınladığımda resmi bir rehberlik yoktu, ancak @ Yaroslov'un (mükemmel ve doğru) cevabında açıklandığı gibi, bu artık geçerli değil: Codelizer artık uyarıyor ve bileşen şablonlarındaki özel değişkenlere yapılan referanslarda AoT derlemesi başarısız olacak . Bununla birlikte, kavramsal düzeyde buradaki her şey geçerli kalır, bu yüzden bu cevabı yardımcı gibi göründüğüm için bırakacağım.


Evet, bu bekleniyor.

privateBileşen / denetleyici / şablonun, Typcript'in hakkında hiçbir şey bilmediği açısal yapılar olduğunu ve diğer erişim değiştiricilerinin dizgi yapısı olduğunu unutmayın . Erişim değiştiriciler sınıflar arasındaki görünürlüğü kontrol eder : Alan oluşturmak, diğer sınıfların ona erişimini privateengeller , ancak şablonlar ve denetleyiciler sınıflar içinde bulunan şeylerdir .

Bu teknik olarak doğru değil, ancak (sınıfların dekoratörler ve meta verileriyle nasıl ilişkili olduğunu anlamak yerine), bunu bu şekilde düşünmek yararlı olabilir, çünkü önemli olan şey (IMHO) şablon ve denetleyici hakkında ayrı olarak düşünmektir. Onları Bileşen yapısının birleşik parçaları olarak düşünmek - bu ng2 zihinsel modelinin ana yönlerinden biridir.

Bu şekilde düşünerek private, bir bileşen sınıfındaki değişkenlerin şablonunda görünür olmasını bekleriz, aynı nedenle privatebu sınıftaki yöntemlerde de görünür olmalarını bekleriz .


3
İlk olarak, aynen çizdiğin gibi düşündüm. Ancak tslint'i 4.02'ye ve codelyzer'ı 2.0.0-beta.1'e yükselttim ve görünümdeki değişkenlere erişirken özel kullanamayacağımı söyleyen hatalar yaşadım. Yani @ Yaroslav'ın cevabı daha uygun görünüyor.
maxime1992

8
Bir bileşen modelinin özel değişkenlerini görememesinin mantıklı olmadığını kabul ediyorum, derleme sırasında muhtemelen aynı sınıfa ezilmeleri gerekir, yani, bileşene özgü özellikleri, nesneleri ve işlevleri diğer tüm bileşenler, şablonunuzda bunları kullanabilmeniz için, dış ayarlardan veya bunlara yapılan çağrılardan bahsetmemek için, bitmiş bileşen üzerinde beklenmedik davranışlara neden olabilir
Felype

1
@ drewmoore, merhaba Sadece birkaç aydır açısal kodlama yapıyorum. Bu sorunla karşı karşıya kaldım. Bununla ilgili başka tartışmalar var mı? Hangi paterni takip edeceğime özgü bir şey bulamadım. imo, değerinde olduğu gibi, kod ayrımını ihlal ediyor gibi görünüyor.
Edgar

2
@drewmoore, anser mantığınıza tamamen katıldığımı söylemeliyim. Korkarım Açısal ekip biraz berbat durumda. AOT modunda, özel üyelere izin vermezler, aksi halde iddia ettikleri belgelerde, özel üyeler söz konusu olduğunda kesinlikle bu konuyu güçlendirir ve sadece bu konuya daha fazla kaos katar. Dokümanlar'dan: "Açısal, bir bileşenin şablonunu bileşene ait olarak ele alır. Bileşen ve şablonu birbirine dolaylı olarak güvenir. Bu nedenle, bileşenin kendi şablonu, bu bileşenin * @ * Girdi dekoratörü olsun veya olmasın herhangi bir özelliğine bağlanabilir. "
Orel Eraki

@drewmoore, Dokümanlar için bağlantı: angular.io/guide/attribute-directives#appendix-why-add-input (Temel olarak Giriş dekoratörüne odaklandığını biliyorum, ancak bahsettiklerinin çoğu sadece ilgili değil it)
Orel Eraki

16

Kod örneği sorunun TypeScript ile ilgili olduğunu belirtmesine rağmen, etiket. Dart için Angular2 de mevcuttur ve bu Dart için dikkate değer bir farktır.

In Dart şablon özel değişkenleri başvuramaz Dart typescript aksine etkili bir biçimde dışarıdan özel üyelerin erişimi engelleyen, çünkü bileşen sınıfının.

Hala bileşen hakkında düşünmek için @ drewmoores öneri ve yine de bir birim olarak şablon geri.

Güncelleme (TS) Angular2 TS'de özel mülklere çevrimdışı derleme erişimi daha sınırlı olacak gibi görünüyor https://github.com/angular/angular/issues/11422


2
Özel değişkenlerin görünüme erişmesini sınırlamak için Typescript derleyicisine sahip olmak mümkün müdür?
Matthew Harwood

Bilmiyorum. Sanırım hayır.
Günter Zöchbauer

2
Onları özel yapmanın, bileşenin ne kadar doğru olduğunu test edebilir? Örneğin, bir test bağlamında bir bileşen oluşturursam, şablon / sınıf etkileşiminin çalıştığını doğrulamak için testimden bu özel yöntemleri çağıramazdım. Bunu henüz denemedim, eğer bu açıksa beni affet :)
Sam Storie

Dart'da testlerde özel üyelere erişemezsiniz. Bunun desteklenip desteklenmeyeceği ve özel API'nin hiç test edilip edilmeyeceği konusunda çok fazla tartışma var. Genel API'yi test etmek her kod yoluna erişebilmelidir. Bunun genel olarak makul olduğunu düşünüyorum. Dart private'de, genel API'yi oldukça geniş yapan IMHO birim testi için çok geniş yapan kitaplık başına (birkaç dosyadan oluşabilir).
Günter Zöchbauer

3

Özel değişkenler bileşen şablonu içinde kullanılabilir. Kılavuz için açısal2 hile sayfasına bakın: https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#parent-to-child-setter

Dizgi yazılarındaki sınıfların kamu / özel üyeleri hakkında daha ayrıntılı bir açıklama burada bulunabilir: https://www.typescriptlang.org/docs/handbook/classes.html .

Tüm üyeler varsayılan olarak Herkese Açıktır. Herkese açık üyelere, sınıf örneği ile birlikte bileşen sınıfının dışından erişilebilir. Ancak özel üyelere sadece sınıf üyesi işlevleri içinde erişilebilir.


İlk bağlantıya baktım ( angular.io/guide/component-interaction#!#parent-to-child-setter ) ve şablonlarda özel değişkenler kullanmanın uygun olduğunu öneren hiçbir yerde göremiyorum. Tersine, şablondan özel değişkenlere erişmek için alıcıları ve ayarlayıcıları kullanırlar.
Sebastien Chartier

3

Geçici çözüm ts dosyasında özel değişkenler kullanmak ve getters kullanmak olabilir.

private _userName = "Test Name";
get userName() {
  return this._userName;
}

Bu iyi bir yaklaşımdır çünkü ts dosyası ve html bağımsız kalır. Ts dosyasında _userName değişken adını değiştirseniz bile, şablon dosyasında herhangi bir değişiklik yapmanız gerekmez.


u _userName _clientName, örneğin, tutarlılık için değiştirirseniz, clientName almak için alıcı değiştirmeniz gerektiğini düşünüyorum ... bu yüzden kazanmak yok
LeagueOfJava

Özel değişkenler için alt çizginin altını çizmek kötü bir uygulamadır.
Florian Leitgeb

1
@FlorianLeitgeb Neden resmi Angular dokümanları yapıyor ? private _name = '';
ruffin

Sonra bu kod snippet'i düzgün gözden geçirilmedi. Buradaki stil rehberinde açıklanan bir stil sözleşmesini takip ederler . Ve ayrıca kendi sayfasında typescript sınıfları bölümünde burada çizgi kullanmıyor.
Florian Leitgeb

1
@FlorianLeitgeb Peki ruffin tarafından yayınlanan bağlantıda gösterildiği gibi setter yöntemlerine müdahale için önerilen çözüm ne olurdu? ie Seter'ınızın özel destek alanına ne diyorsunuz?
El Ronnoco

1

Kısa yanıt hayır, teknik olarak TS dosyasından ayrıldığı için şablondan özel üyelere erişememeniz gerekir.


0

Tsconfig.app.json dosyasında derleyici seçeneklerinde 'fullTemplateTypeCheck' seçeneğini belirtirseniz, proje oluşturma sırasında projenizin html dosyalarındaki tüm geçersiz referansları görebilirsiniz.

"angularCompilerOptions": {
"enableIvy": true,
"fullTemplateTypeCheck": true

}

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.