속성 'X'는 비공개이며 'xyzComponent'클래스 내에서만 액세스 할 수 있습니다.


100

블로그 를 팔로우하고있는 프로덕션 용 angular2 애플리케이션을 구축하려고합니다 . 내 ngc 성공적인 컴파일 후 tsc 컴파일 이 수행되면 이미지에 표시된 오류가 생성됩니다.

여기에 이미지 설명 입력

잠시 검색 한 후 "컨텍스트 속성" 섹션 에서 문제를 설명하는 이 블로그 를 발견했습니다.이 블로그 는 제대로 이해할 수없는 문제가 발생하고 있다는 좋은 생각을 줄 수 있습니다. 기본적으로 변수를 private으로 만들 때 "ERROR : Property is private and only access within class"라는 메시지가 표시 됩니다. 나는 그것이 왜 오는지 이해하지 못한다.

지난 며칠 동안이 문제에 머리를 두드리는 동안 친절하게 도와주세요.


1
부동산을 개인에서 공용으로 변경하려고 했습니까?
Xin Meng

오류가 발생하는 TS 파일 콘텐츠를 공유해 주시겠습니까?
Raj

답변:


142

주어진 구성 요소의 경우 템플릿에서 액세스하는 모든 구성원 (메서드, 속성)은 AOT 컴파일 시나리오에서 공용이어야합니다. 이는 템플릿이 TS 클래스로 바뀌었기 때문입니다. 생성 된 클래스와 구성 요소는 이제 두 개의 개별 클래스이며 클래스 간 개인 멤버에 액세스 할 수 없습니다.

간단히 말해서 미리 컴파일을 사용하려는 경우 템플릿의 비공개 멤버에 액세스 할 수 없습니다.

더 나은 설명을 위해 https://github.com/angular/angular/issues/11422


그러나 이것은 Angular의 이전 버전이 아닙니다. 최신 버전으로 업그레이드 한 후 이러한 오류가 발생하기 시작했습니다.
Emil

35

더 간단한 또 ​​다른 대답은 다음과 같습니다.

여러분, HTML에서 개인 메서드, 필드 또는 속성을 호출하지 마십시오. :)


PS는 컴파일 할 때 *.ts코드를 *.js, AOT의 와 비공개 회원을 연결하는 쓰레기 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 nameINF이다. 재귀
vp_arth

@vp_arth? 하나는 로컬이고 하나는 글로벌입니까? 같은 이름으로도 2 가지 다른 것 같아요? 유 사용하는 이유 이잖아 this.세계 하나에 포인트
LazerBanana

로컬 / 글로벌에서 무엇을 의미합니까? name변수가 아니라 객체 속성입니다. 해당 객체에 대해 this.name = namesetter ( set name(v){})를 트리거 합니다. 테스트하기 너무 쉬움 : blitz Maximum call stack size exceeded
vp_arth

6

이것은 나를 위해 작동합니다. 단순히 서비스를 공개로 변경하십시오.

constructor(public service: SpecificObjectService) { }

생산중인 앱 !!


따라서 위의 @TiyebM의 답변과 덜 상세한 답변을 가진 똑같은 솔루션입니다.
Ash

0

좋아요, 이것은 정말 간단한 자바 스크립트 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.