简体   繁体   中英

Is there a way to restrict method/variable access to the component and it's template?

When I access a childcomponent using @ViewChild, I get access to all it's public methods. However, some of those methods are specifically written for template interaction and shouldn't be accessible for another (parent) component. You need to set variables/methods to public in order for your template to be able to use them, but doing so also breaks encapsulation.

Does anyone know of a way to restrict variable/method access to only the component, it's template and it's test? For example like the package-private modifier in Java?

In the following code, a parent-component is able to access the component via @ViewChild(TestComponent) and then call testComponent.showMessage$.next('something totally unrelated') . How can I define that this is functionality that I don't want to expose?

@Component({
  selector: 'app-aanvraag',
  template: `
    <div *ngIf="showMessage$ | async as message">
      {{message}}
    </div>`,
  styleUrls: ['./aanvraag.component.scss']
})
export class TestComponent {
  showMessage$ = new BehaviorSubject('Some message');

  constructor() {
  }
}

In your specific example you can use the asObservable() . This makes sure that anything outside the component cannot call next() . Although this will also make it so that you can't call that from the template.

Unfortunately there is no way to make it just available in the template, and not available for any other piece of code that might have access to the instance. I remember 2 years ago when they added the check in the angular compiler, I had all my properties which were used in the template set as private . Was a big job to make them all public.

For a more descriptive code, you can make the things that are used in the template not have an access identifier, and what should be part of the public API you can add the public property. This will not prevent access, but makes it more clear.

You can also have a look at the readonly access identifier. This prevents anything from reassigning said property:

@Component({
  selector: 'app-aanvraag',
  template: `
    <div *ngIf="showMessage$ | async as message">
      {{message}}
    </div>`,
  styleUrls: ['./aanvraag.component.scss']
})
export class TestComponent {
  private readonly showMessage = new BehaviorSubject('Some message');

  readonly showMessage$ = this.showMessage.asObservable();

  constructor() {
  }

  newMessage(message: string): void {
    this.showMessage.next(message);
  } 
}

If you want to have a property from a component just to have read access to the outside (including the template), you can use a getter:

export class TestComponent {
  get message(): string {
    return this._message;
  }

  private message: string = '';
}

for code quality reasons, a small suggestion, use english naming with components and templates

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM