Должен ли Angular2 @Inputs быть общедоступными или мы можем / должны иметь более строгий API, сделав их закрытыми?
Я использую Angular2 с Typescript
Предположим, у меня есть следующее в шаблоне моего компонента приложения:
...
<coffee-cup [coffee]=""
...
мой coffee-cup
составная часть:
@Component({
selector: 'coffee-cup',
...
})
export class CoffeeCup {
@Input()
public coffee = 0;
}
В настоящее время я не уверен, как должен выглядеть мой вклад. Это может выглядеть так:
@Input()
public coffee = 0;
Или же
@Input()
private coffee = 0;
В настоящее время я склоняюсь к тому, чтобы сделать кофе с переменным членом приватным.
- Я хочу определить понятный публичный API для компонента
- Я только хочу выставить настройку свойства кофе через шаблон
- В настоящее время у меня нет никаких причин, чтобы кофе можно было читать или устанавливать непосредственно из родительского компонента. Если возникнет необходимость, я могу отказаться от частного модификатора.
Я рассматриваю компонент так, что есть два отдельных API для взаимодействия с ним:
- Шаблон API, который состоит из
@Inputs
а также@Outputs
- API Typescript, который состоит из всех открытых свойств и методов
Я не проверял, что происходит в следующей ситуации, однако, это может изменить ответ:
- Предположим, что член кофе является публичным. Если мой
appComponent
получает доступ кCoffeeCup
с помощью@ViewChild
и устанавливает член кофе, будут ли крючки жизненного цикла (какngOnChange
) Пожар?
Переформулировать вопрос: следует Angular2 @Input
s должны быть публичными или мы можем / должны иметь более строгий API, сделав их приватными?
1 ответ
Во-первых, с точки зрения дизайна API @Input
подразумевает общественность. Это также верно с угловой точки зрения, эти декораторы описывают интерфейс для взаимодействия с компонентом.
@Input
decorator или любой другой мета-декоратор используется angular таким образом, чтобы angular знал о вашем намерении и лучше понимал шаблон и его связи с классом компонента.
В некоторых случаях он также используется механизмом обнаружения изменений. Например, @Input
это поле, отслеживаемое обнаружением изменений, оно указывает на механизм CD, что это свойство должно контролироваться.
Имея частную собственность с @Input
декоратор не должен иметь никакого эффекта во время выполнения. Этот модификатор является виртуальным, и он пропал после компиляции TypeScript в JavaScript.
Однако в зависимости от вашей среды могут возникнуть некоторые эффекты:
Большим преимуществом наличия TypeScript и метаданных в целом является наличие интеллектуальной IDE, что означает, что IDE может помочь вам во время кодирования. Наличие частной собственности может или не может повлиять на это в зависимости от реализации каждой IDE. имеющий @Input
для свойства приведет к тому, что среда IDE покажет вам это свойство в окне intellisense при написании HTML-разметки для этого компонента.
Другим фактором риска является будущая поддержка минимизации / углификации в машинописи. Частные свойства, как следует из названия, нигде больше не используются внутри класса. Эта особенность означает, что компилятор может изменять имена частных свойств, чтобы они занимали меньше байтов, а также делает их "более частными", так как идентификатор может меняться от сборки к сборке. Например: private mySpecialProperty: string
после минификации будет p1
и компилятор изменит все ссылки на этот идентификатор в классе, чтобы соответствовать p1
, Таким образом, наличие этого сегодня будет работать, но в будущем это может ограничить возможности сборки.
Еще один момент, который следует учитывать: в то время как angular не заботится о модификаторах, которые делает ваш компилятор, создание динамических компонентов будет ограничено. Другими словами, создание компонентов в HTML-разметке будет работать без проблем, но динамическое создание компонентов с использованием ComponentResolver -> ComponentFactor
будет ограничен, так как вы не сможете назначить эти входные данные экземпляру ваших компонентов с помощью кода. Если вы не планируете это делать, вы в порядке.
Если вы создаете компоненты, которые будут использоваться другими, публичный модификатор обязателен для
@Input/@Output
, Пользователи вашего компонента должны иметь возможность динамически создавать ваши компоненты.
Это также отвечает на вопрос о доступе к этим свойствам в родительском / дочернем компоненте, получая ссылку на компонент кофе. Привязка будет возможна только через разметку шаблона. Например, вы не сможете вручную зарегистрироваться на EventEmitter
s зарегистрированы на компонент кофе. Это иногда требуется, см. ЭТОТ сценарий в качестве одного примера.
Что касается хуков жизненного цикла, это не должно иметь никакого эффекта, так как angular не проверяет тип, но проверяет наличие.
Итак, подведем итог: в большинстве случаев использования у вас не должно быть проблем, но по мере развития приложения вы можете решать некоторые проблемы или нет. Возможно, вам также придется отказаться от расширенных функций минимизации в будущем...