简体   繁体   English

有没有办法限制对组件及其模板的方法/变量访问?

[英]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. 当我使用@ViewChild访问子组件时,我可以访问它的所有公共方法。 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. 您需要将变量/方法设置为public才能使模板能够使用它们,但这样做也会破坏封装。

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? 例如,像Java中的package-private修饰符?

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') . 在下面的代码中,父组件能够通过@ViewChild(TestComponent)访问组件,然后调用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() . 在您的具体示例中,您可以使用asObservable() This makes sure that anything outside the component cannot call next() . 这可以确保组件外部的任何内容都无法调用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 . 我记得2年前,当他们在角度编译器中添加了检查时,我将我在模板集中使用的所有属性设置为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. 对于更具描述性的代码,您可以使模板中使用的内容不具有访问标识符,以及应该添加public属性的公共API的一部分。 This will not prevent access, but makes it more clear. 这不会阻止访问,但会更清楚。

You can also have a look at the readonly access identifier. 您还可以查看readonly访问标识符。 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: 如果您希望组件中的属性只是对外部(包括模板)具有读访问权限,则可以使用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 出于代码质量的原因,一个小建议,使用英文命名与组件和模板

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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