programing

Angular2 - 템플릿에서 개인 변수에 액세스할 수 있어야 합니까?

abcjava 2023. 3. 27. 20:52
반응형

Angular2 - 템플릿에서 개인 변수에 액세스할 수 있어야 합니까?

가 " " "로 선언된 private컴포넌트 클래스의 경우 해당 컴포넌트의 템플릿에서 액세스할 수 있어야 합니까?

@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
}

업데이트

Angular 14 이후, 결합할 수 있습니다.protected이치노이를 통해 내부 상태(템플릿에만 액세스 가능)가 컴포넌트의 퍼블릭 API로 노출되는 문제를 부분적으로 해결할 수 있습니다.


아니요, 템플릿에서 개인 변수를 사용하면 안 됩니다.

나는 드류무어의 답변을 좋아하고 그 안에 있는 완벽한 개념 논리를 보았지만, 실행 면에서는 틀렸다.템플릿은 컴포넌트 클래스 내에 존재하지 않지만 컴포넌트 클래스 외부에 존재합니다.증거를 찾기 위해보고서를 보세요.

TypeScript가 있기 입니다.private키워드가 멤버를 사적으로 만들지는 않아요.Just-in-Time 컴파일은 런타임에 브라우저에서 이루어지며 JS에는 개인 멤버에 대한 개념이 없습니다(아직은?).날 바른 길로 인도한 건 샌더 엘리아스 덕분이야

★★★★★★★★★★★★★★★★ ngc또한 사전 컴파일에서는 템플릿에서 컴포넌트의 개인 멤버에 액세스하려고 하면 오류가 발생합니다. 클론 , 변경, 변경MyComponent오류가 합니다.ngc사전 컴파일에 대한 답변도 다음과 같습니다.

편집: 이 답변은 현재 올바르지 않습니다.투고했을 때는, 그 토픽에 관한 공식적인 가이던스는 없었습니다만, @Yaroslov의 (훌륭하고 올바른) 답변에서 설명한 바와 같이, 이것은 더 이상 사실이 아닙니다.이제 Codelizer가 경고하고 구성 요소 템플릿의 개인 변수에 대한 참조에서 AoT 컴파일이 실패합니다.단, 개념적으로는 모든 것이 유효하기 때문에 이 답변은 도움이 될 것으로 생각되므로 남겨두겠습니다.


네, 예상된 일입니다.

주의해 주세요private기타 접근 수식자는 Typscript 구성체이며, 컴포넌트/컨트롤러/템플릿은 Typscript에 대해 아무것도 모르는 각도 구성체입니다.액세스 수식자는 클래스 간의 가시성을 제어합니다.필드 만들기private는 다른 클래스가 이 클래스에 액세스할 수 없도록 하지만 템플릿과 컨트롤러는 클래스 내에 존재하는 것입니다.

엄밀히 말하면 그렇지 않지만 (클래스와 데코레이터의 메타데이터의 관계를 이해하는 대신) 이렇게 생각하면 도움이 될 수 있습니다.IMHO(중요한 것)는 템플릿과 컨트롤러를 별개의 실체로 생각하는 것에서 컴포넌트 구성의 통합된 부분으로 생각하는 것으로 전환하는 것입니다.이것은 ng2 멘탈 모델의 주요 측면 중 하나입니다.

그런 식으로 생각하면, 분명히 우리는private할 수 로 컴포넌트 변수도 할 수 .이러한 이유와 같은 이유로 컴포넌트 클래스의 변수는private그 클래스의 메서드.

코드 예제는 질문이 TypeScript에 관한 것임을 나타내지만 태그는 없습니다.Angular2는 Dart에서도 사용할 수 있으며, 이것은 Dart와 현저한 차이입니다.

Dart에서는 템플릿은 컴포넌트 클래스의 개인 변수를 참조할 없습니다.TypeScript와 달리 Dart는 외부에서 개인 멤버의 접근을 효과적으로 차단하기 때문입니다.

컴포넌트와 템플릿에 대해 하나의 유닛으로 생각하기 위한 @drewmoores의 제안을 아직도 기억하고 있습니다.

업데이트(TS) 오프라인 컴파일을 통해 개인 자산에 대한 접근은 Angular2 TS에서도 더욱 제한될 것으로 보입니다.https://github.com/angular/angular/issues/11422

회피책은 ts 파일의 개인 변수와 getter를 사용하는 것입니다.

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

ts 파일과 html은 독립적이기 때문에 이는 좋은 접근법입니다.ts 파일에서 _userName 변수 이름을 변경하더라도 템플릿 파일을 변경할 필요가 없습니다.

개인 변수는 구성 요소 템플릿 내에서 사용할 수 있습니다.https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#parent-to-child-setter에서 angular2 치트 시트를 참조하십시오.

타이프스크립트내의 클래스의 퍼블릭/프라이빗 멤버에 대한 자세한 설명은, https://www.typescriptlang.org/docs/handbook/classes.html 를 참조해 주세요.

기본적으로 모든 구성원은 Public입니다.공용 구성원은 클래스 인스턴스와 함께 구성 요소 클래스 외부에서 액세스할 수 있습니다.그러나 개인 구성원은 클래스 구성원 기능 내에서만 액세스할 수 있습니다.

즉, 템플릿은 기술적으로 TS 파일과 분리되어 있기 때문에 템플릿에서 개인 멤버에 액세스할 수 없습니다.

tsconfig.app.json에서 'fullTemplate를 지정한 경우컴파일러 옵션의 Type Check' 옵션은 프로젝트 빌드 시 프로젝트의 html 파일에 있는 모든 비활성 참조를 볼 수 있습니다.

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

}

조금 늦었다는 것은 알지만, 저는 Angular2부터 이 문제에 대해 사전에 알고 있었습니다.마지막으로 적절한 컴포넌트 API를 갖추고 적절한 타입 체크가 있는 템플릿에서 이들 컴포넌트 내의 개인 필드에 접근할 수 있는 좋은 회피책을 생각해냈습니다.

export interface MyComponentPrivateProperties {
    _label: string;
}
export class MyComponent {
    private _label: string = 'Label';

    public get view(): MyComponentPrivateProperties {
        return this as any;
    }
}
<div>{{view._label}}</div>

이렇게 하면 보시다시피 html 템플릿과 컴포넌트의 적절한 API에 균등하게 타입 체크와 필요한 모든 것을 할 수 있습니다.다른 컴포넌트에서는MyComponent다음과 같은 클래스:

export class OtherComponent {
    private _m: MyComponent;

    ngOnInit() {
        // here, this._label is not visible.
    }
}

우리는 그 재산에 주목하게 될 것이다._label는 표시되지 않습니다.

물론, 이 수업들은MyComponent인터페이스를 실장하지 않는다.MyComponentPrivateProperties이 인터페이스에는 실장은 없습니다.이것은 각도에 대한 설명일 뿐입니다.ngc컴파일러.컴파일러는 컴파일 시 템플릿에서 접근할 수 있어야 하는 개인 속성을 알려주고 실행 시 사라집니다.

언급URL : https://stackoverflow.com/questions/34574167/angular2-should-private-variables-be-accessible-in-the-template

반응형