คุณสมบัติ 'X' เป็นแบบส่วนตัวและสามารถเข้าถึงได้เฉพาะในคลาส 'xyzComponent'


102

ฉันกำลังพยายามสร้างแอปพลิเคชั่น angular2 สำหรับการผลิตที่ฉันติดตามบล็อกนี้ หลังจากการคอมไพล์ngcของฉันประสบความสำเร็จเมื่อการคอมไพล์ tscเกิดขึ้นมันจะสร้างข้อผิดพลาดด้านล่างที่แสดงในภาพ:

ป้อนคำอธิบายภาพที่นี่

หลังจากค้นหาอยู่สักพักฉันก็พบบล็อกนี้ซึ่งอธิบายปัญหาในส่วน"คุณสมบัติบริบท"ซึ่งฉันไม่สามารถเข้าใจได้อย่างถูกต้องอาจเป็นเพราะมีความคิดที่ดีกับคุณว่าเกิดอะไรขึ้น โดยพื้นฐานแล้วเมื่อเราสร้างตัวแปรให้เป็นส่วนตัวเราจะได้รับ"ข้อผิดพลาด: คุณสมบัติเป็นส่วนตัวและสามารถเข้าถึงได้ภายในคลาสเท่านั้น" ฉันไม่เข้าใจว่าทำไมมันถึงมา

กรุณาช่วยเราในขณะที่เรากำลังเผชิญหน้ากับปัญหานี้ในช่วงสองสามวันที่ผ่านมา


1
คุณได้พยายามเปลี่ยนทรัพย์สินจากส่วนตัวเป็นสาธารณะหรือไม่?
Xin Meng

คุณช่วยกรุณาแบ่งปันเนื้อหาไฟล์ ts ที่มีข้อผิดพลาดในการขว้างปาได้ไหม
Raj

คำตอบ:


143

สำหรับองค์ประกอบที่กำหนดสมาชิกทั้งหมด (วิธีการคุณสมบัติ) ที่เข้าถึงโดยเทมเพลตจะต้องเป็นสาธารณะในสถานการณ์การรวบรวม AOT เนื่องจากเทมเพลตถูกเปลี่ยนเป็นคลาส TS คลาสที่สร้างขึ้นและคอมโพเนนต์เป็น 2 คลาสแยกกันในขณะนี้และคุณไม่สามารถเข้าถึงสมาชิกส่วนตัวข้ามคลาสได้

กล่าวโดยย่อ: คุณไม่สามารถเข้าถึงสมาชิกส่วนตัวในเทมเพลตของคุณได้หากคุณต้องการใช้การรวบรวมล่วงหน้า

เพื่อการอธิบายที่ดีขึ้นhttps://github.com/angular/angular/issues/11422


แต่นี่ไม่ใช่ Angular รุ่นก่อนหน้าไม่ใช่เหรอ? ฉันเริ่มได้รับข้อผิดพลาดเหล่านั้นหลังจากอัปเกรดเป็นเวอร์ชันใหม่ล่าสุด
Emil

37

บางทีคำตอบที่ง่ายกว่านั้นก็คือ:

พวกโปรดอย่าเรียกเมธอดส่วนตัวฟิลด์หรือคุณสมบัติจาก HTML :)


PS เมื่อรวบรวม*.tsรหัส*.js, ทอทปฏิเสธที่จะเชื่อมต่อสมาชิกที่ไม่ใช่แบบสาธารณะกับHTMLแม่แบบ

และ "ใช่" สิ่งนี้จะทำให้การสร้างไปป์ไลน์ของคุณล้มเหลว: D


1
หรือเข้าถึงสนามส่วนตัว / คุณสมบัติ!
JMK

@Arsen Khachaturyan It`s funny)
voodoo417

@JMK ฉันได้อัปเดตโพสต์ตามคำแนะนำของคุณขอบคุณ
Arsen Khachaturyan

@ voodoo417 ตลกและจริง;). บางครั้งคำตอบเชิงวิชาการมากเกินไปอาจทำให้ใคร ๆ สนใจได้และเราก็ต้องง่ายกว่าที่จะทำได้
Arsen Khachaturyan

1
@Arsen Khachaturyan เห็นด้วย Arsen +++
voodoo417

17

ฉันได้รับสิ่งนี้เมื่อฉันประกาศหัวฉีดส่วนตัวในตัวสร้าง:

constructor(private service: SpecificObjectService) { }

และใช้ในเทมเพลต:

*ngFor="let pd of service.listSpecificObject "

วิธีแก้ปัญหาคือ:

constructor(public service: SpecificObjectService) { }

16

ดังนั้นฉันจึงแก้ไขปัญหานี้ฉันจะทำให้มันสั้นและเรียบง่าย เพื่อแก้ไขปัญหานี้ฉันอ่านบล็อกนี้อย่างละเอียด ในส่วน " คุณสมบัติบริบท " วิธีแก้ปัญหานี้คืออย่าใช้หรือสร้างตัวแปรส่วนตัวหากคุณต้องการใช้ในมุมมองโดยตรงเมื่อคุณกำลังสร้างงานสร้างกับ AOT ( เช่น Ahead Of Time ) สำหรับ การผลิต

*ตัวอย่างเช่น *

// 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;
    }
  }
}

เอาต์พุต: พ ร็อพเพอร์ตี้ '_initials' เป็นแบบส่วนตัวและเข้าถึงได้เฉพาะในคลาส 'ThirdPartyComponent'

วิธีการแก้:

อัปเดตสิ่งนี้private _initials: string;เป็นเพียง_initials: string;

สำหรับคำตอบนี้Harish Gadiyaให้ความช่วยเหลือฉันขอบคุณสำหรับสิ่งนั้น


ไม่จำเป็นต้องใช้ที่_nameนั่นอาจเป็นเช่นเดียวกับที่คุณใช้this.และอื่น ๆnameเป็นตัวแปรท้องถิ่นthis.name=name;
LazerBanana

@LazerBanana แต่this.name=nameในนั้นset nameคือ inf. recursion
vp_arth

@vp_arth? หนึ่งในท้องถิ่นคือระดับโลก? แม้จะมีชื่อเดียวกัน 2 สิ่งที่แตกต่างกันฉันเดา? นั่นคือเหตุผลที่คุณใช้this.ชี้ไปที่ระดับโลก
LazerBanana

คุณหมายถึงอะไรภายใต้ local / global? nameไม่ใช่ตัวแปร แต่เป็นคุณสมบัติของวัตถุ this.name = nameจะทริกเกอร์ setter ( set name(v){}) บนวัตถุนั้น ทดสอบได้ง่ายมาก: blitz Maximum call stack size exceeded
vp_arth

6

สิ่งนี้ใช้ได้กับฉัน: เพียงแค่เปลี่ยนบริการเป็นสาธารณะ

constructor(public service: SpecificObjectService) { }

แอปทำงานในการผลิต !!


ดังนั้นคำตอบเดียวกันกับคำตอบที่ละเอียดน้อยกว่าคำตอบของ @ TiyebM ด้านบน
เถ้า

1

ตกลงเห็นว่านี่เป็นปัญหา javascript es6 ที่เรียบง่ายหากคุณต้องเก็บประเภทข้อมูลไว้เป็นส่วนตัวคุณสามารถทำได้

privateAccess(){
     return this.cannotAccessByInstanceButStillNeeded
}

0

หากคุณต้องการใช้เราเตอร์ในมุมมองโปรดทำให้เป็นสาธารณะ

เช่น:

<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 ส่งเมลเตือนมาหาฉัน

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.