Должен ли 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 для взаимодействия с ним:

  1. Шаблон API, который состоит из @Inputs а также @Outputs
  2. 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, Пользователи вашего компонента должны иметь возможность динамически создавать ваши компоненты.

Это также отвечает на вопрос о доступе к этим свойствам в родительском / дочернем компоненте, получая ссылку на компонент кофе. Привязка будет возможна только через разметку шаблона. Например, вы не сможете вручную зарегистрироваться на EventEmitters зарегистрированы на компонент кофе. Это иногда требуется, см. ЭТОТ сценарий в качестве одного примера.

Что касается хуков жизненного цикла, это не должно иметь никакого эффекта, так как angular не проверяет тип, но проверяет наличие.

Итак, подведем итог: в большинстве случаев использования у вас не должно быть проблем, но по мере развития приложения вы можете решать некоторые проблемы или нет. Возможно, вам также придется отказаться от расширенных функций минимизации в будущем...

Другие вопросы по тегам