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
}

Ответ 1

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

Пока мне нравится ответ drewmoore и вижу в нем идеальную концептуальную логику, в противном случае это неправильно. Шаблоны не существуют в классах компонентов, но вне их. Посмотрите это репо для доказательства.

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

При компиляции ngc и Ahead-of-Time вы получите ошибки, если попытаетесь получить доступ к частным членам компонента из шаблона. Повторите демонстрацию клонов, измените видимость членов MyComponent на личную, и при запуске ngc вы получите ошибки компиляции. Здесь также answer для компиляции Ahead-of-Time.

Ответ 2

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


Да, это ожидается.

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

Это не технически верно, но (вместо понимания того, как классы относятся к декораторам и их метаданным), может быть полезно подумать об этом таким образом, потому что важная вещь (ИМХО) заключается в переходе от мышления о шаблоне и как отдельные субъекты, рассматривая их как единые части Компонента - это один из основных аспектов ментальной модели ng2.

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

Ответ 3

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

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

Я все еще поддерживаю предложение @drewmoores подумать о компоненте и его шаблоне как о едином модуле.

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

Ответ 4

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

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

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

Ответ 5

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

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

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

Ответ 6

Краткий ответ: нет, у вас не должно быть доступа к закрытым элементам из шаблона, поскольку он технически отделен от файла TS.