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 ответов:
редактировать: этот ответ будет неправильным. не было официального руководства по этой теме, когда я опубликовал его, но, как объяснено в ответе @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, вам не нужно вносить никаких изменений в файл шаблона.