'X' özelliği özeldir ve yalnızca 'xyzComponent' sınıfından erişilebilir


102

Bu blogu takip ettiğim için üretim için angular2 uygulaması oluşturmaya çalışıyorum . Ngc başarılı derlememden sonra tsc derlemesi gerçekleştiğinde, görüntüde gösterilen aşağıdaki hatayı oluşturur:

görüntü açıklamasını buraya girin

Bir süre aradıktan sonra , tam olarak anlayamadığım "Bağlam özelliği" bölümünde sorunu açıklayan bu blogu buldum , neyin yanlış olduğu konusunda size iyi bir fikir verebilir. temelde bir değişkeni özel yaptığımızda "HATA: Mülk özeldir ve yalnızca sınıf içinde erişilebilir" mesajı alıyoruz . Neden geldiğini anlamıyorum.

Geçtiğimiz birkaç gündür bu soruna kafa yorarken bize yardım edin.


1
Mülkü özelden kamuya değiştirmeyi denediniz mi?
Xin Meng

Hata veren ts dosya içeriğini paylaşır mısınız?
Raj

Yanıtlar:


143

Belirli bir bileşen için, şablonu tarafından erişilen tüm üyeleri (yöntemler, özellikler) AOT derleme senaryosunda herkese açık olmalıdır. Bunun nedeni, şablonun TS sınıfına dönüştürülmesidir. Oluşturulan bir sınıf ve bir bileşen artık 2 ayrı sınıftır ve sınıflar arası özel üyelere erişemezsiniz.

Kısacası, önceden derlemeyi kullanmak istiyorsanız şablonlarınızdaki özel üyelere erişemezsiniz.

Daha iyi açıklama için https://github.com/angular/angular/issues/11422


ama bu Angular'ın önceki sürümleri değildi, değil mi? en yeni sürüme yükselttikten sonra bu hataları almaya başladım.
Emil

37

Belki daha da basit bir cevap şudur:

Çocuklar, lütfen HTML'den özel yöntemleri, alanları veya özellikleri çağırmayın :)


PS, *.tskodu derlerken AOT*.js , genel olmayan üyeleri HTML şablonuna bağlamayı reddediyor .

Ve "evet" bu, derleme ardışık düzeninizin başarısız olmasına neden olur: D


1
Veya özel alanlara / mülklere erişin!
JMK

@Arsen Khachaturyan Komik)
voodoo417

@JMK Gönderiyi önerinize göre güncelledim, teşekkür ederim.
Arsen Khachaturyan

@ voodoo417, komik ve gerçek;). Bazen çok akademik cevaplar gerçekten herkesin aklını uçurabilir ve elimizden geldiğince basit olmalıyız.
Arsen Khachaturyan

1
@Arsen Khachaturyan Katılıyorum, Arsen +++
voodoo417

17

Bunu yapıcıda özel enjektabl bildirdiğimde aldım:

constructor(private service: SpecificObjectService) { }

Ve bunları şablonda kullandı:

*ngFor="let pd of service.listSpecificObject "

Çözüm şudur:

constructor(public service: SpecificObjectService) { }

16

Bu yüzden bu sorunu çözdüm, bunu kısa ve basit tutacağım. Bunu düzeltmek için bu blogu derinlemesine okudum . " Bağlam özelliği " bölümünde olduğu gibi Bu sorunun çözümü şudur : Yapınızı AOT ile oluştururken doğrudan görünümde kullanmak istiyorsanız, bir özel değişken kullanmayın veya oluşturmayın ( yani, Ahead Of Time ) için üretim.

*Örneğin *

// component.ts
@Component({
  selector: 'third-party',
  template: `
    {{ _initials }}
  `
})
class ThirdPartyComponent {
  private _initials: string;
  private _name: string;

  @Input()
  set name(name: string) {
    if (name) {
      this._initials = name.split(' ').map(n => n[0]).join('. ') + '.';
      this._name = name;
    }
  }
}

çıktı: '_initials' özelliği özeldir ve yalnızca 'ThirdPartyComponent' sınıfından erişilebilir.

Çözüm:

private _initials: string;bunu basitçe güncelle_initials: string;

Bu cevap için Harish Gadiya bana bunun için çok yardım et.


orada kullanmaya gerek yok, kullandığınızla _nameaynı olabilir this.ve diğer nameyerel bir değişkenithis.name=name;
LazerBanana

@LazerBanana, Ama this.name=nameiçinde set nameinf olduğunu. yineleme
vp_arth

@vp_arth? biri yerel mi, küresel mi? hatta aynı isimde 2 farklı şey var sanırım? bu yüzden this.küresel olanı işaret etmek için kullanıyorsunuz
LazerBanana

Yerel / küresel altında ne demek istiyorsun? namedeğişken değil, nesne özelliğidir. o nesne üzerinde this.name = namesetter ( set name(v){}) 'i tetikleyecektir . Test etmesi çok kolay: yıldırım Maximum call stack size exceeded
vp_arth

6

Bu benim için çalışıyor çocuklar: Basitçe hizmeti halka açın.

constructor(public service: SpecificObjectService) { }

Uygulama üretimde çalışıyor !!


Dolayısıyla, yukarıdaki @ TiyebM'nin cevabı ile daha az ayrıntılı bir cevapla aynı çözüm.
Kül

1

Tamam, bunun gerçekten basit bir javascript es6 problemi olduğunu görün, veri türünü gizli tutmanız gerekiyorsa, bunu kolayca yapabilirsiniz

privateAccess(){
     return this.cannotAccessByInstanceButStillNeeded
}

0

Yönlendiriciyi görünümde kullanmak istiyorsanız, lütfen onu genel yapın.

Örneğin:

<button 
   [routerLink]="['/login']"
   [queryParams]="{redirectTo: router.url}"
   translate="Please sign in to use this feature"
/>
import { Router } from '@angular/router'; 

constructor(
   public router: Router; // don't make it private
) {}

Github CI bana bir uyarı mesajı gönderene kadar bunu görmezden geldim.

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.