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
}
5 94

5 ответов:

редактировать: этот ответ будет неправильным. не было официального руководства по этой теме, когда я опубликовал его, но, как объяснено в ответе @Yaroslov (отлично и правильно), это уже не так: Codelizer теперь предупреждает, и компиляция AoT не будет работать со ссылками на частные переменные в шаблонах компонентов. Тем не менее, на концептуальном уровне все здесь остается в силе, поэтому я оставлю этот ответ, поскольку он, похоже, был полезен.


Да, это ожидаемый.

имейте в виду, что private и другие модификаторы доступа являются конструкциями Typescript, тогда как компонент/контроллер/шаблон-это угловые конструкции, о которых Typescript ничего не знает. Модификаторы доступа управляют видимостью между классы: создание поля private предупреждает другие классы от наличия доступа к нему, но шаблоны и контроллеры-это вещи, которые существуют внутри классы.

это не технически верно, но (вместо понимания того, как классы относятся к декораторам и их метаданным), было бы полезно подумать об этом таким образом, потому что важно (IMHO) перейти от мышления о шаблоне и контроллере как отдельных сущностях к мышлению о них как о единых частях компонентной конструкции - это один из основных аспектов ментальной модели ng2.

думая об этом таким образом, очевидно, мы ожидаем private переменные в классе компонентов, которые должны быть видны в его шаблон, по той же причине мы ожидаем, что они будут видны в private методы этого класса.

нет, вы не должны использовать закрытые переменные в шаблонах.

а мне нравится drewmoore по и увидеть совершенную концептуальную логику в нем, реализация по-разному это неправильно. Шаблоны существуют не внутри классов компонентов, а вне их. Взгляните на этот РЕПО для доказательства.

единственная причина, почему это работает, потому что TypeScript private ключевое слово на самом деле не делает член частным. Just-In-Time компиляция происходит в браузер во время выполнения и JS не имеет никакого понятия о частных членах (пока?). Кредит идет на Сандер Элиас поставив меня на правильный путь.

С ngc и опережающая компиляция, вы получите ошибки, если вы попытаетесь получить доступ к частным членам компонента из шаблона. Клонировать демонстрационное РЕПО, изменить MyComponent видимость членов в private и вы получите ошибки компиляции, при запуске ngc. Вот также ответ специфические для Опережающая компиляция.

несмотря на то, что пример кода указывает, что вопрос касается TypeScript, у него нет typescript тег. Angular2 также доступен для дротика, и это заметное отличие от Дротика.

на Дарт the шаблон не может ссылаться на частные переменные класса компонентов, потому что Dart в отличие от TypeScript эффективно предотвращает доступ частных членов извне.

Я все еще назад @ drewmoores предложение подумайте о компоненте, и это шаблон как одно целое, хотя.

обновление (TS) Похоже, что с автономной компиляцией доступ к частным свойствам станет более ограниченным и в Angular2 TShttps://github.com/angular/angular/issues/11422

частные переменные могут использоваться в шаблоне компонента. См. angular2 шпаргалка для руководства: https://angular.io/docs/ts/latest/cookbook/component-communication.html#!#parent-to-child-setter

более подробное объяснение по открытым / закрытым членам классов в typescript можно найти здесь:https://www.typescriptlang.org/docs/handbook/classes.html.

все члены по умолчанию являются открытыми. Открытые члены могут быть доступны из-за пределов класса компонента вместе с классом-экземпляром. Но частные члены могут быть доступны только внутри функций-членов класса.

обходным путем может быть использование частных переменных в файле ts и использование геттеров.

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

это хороший подход, потому что файл ts и html остаются независимыми. Даже если вы измените имя переменной _userName в файле ts, вам не нужно вносить никаких изменений в файл шаблона.