«Частный» и «общедоступный» в компоненте Angular

120

Если я не добавляю приватные ранее foo, loadBarи text, я считаю, что они общедоступны по умолчанию.

export class RandomComponent {
  @Input() foo: string;
  @Output() loadBar = new EventEmitter();
  text: string;
}

Есть ли какой-либо вариант использования, когда они находятся publicв компоненте?

Должен ли я всегда добавлять privateдля всех из них, как показано ниже, по соображениям инкапсуляции / безопасности ?

export class RandomComponent {
  @Input() private foo: string;
  @Output() private loadBar = new EventEmitter();
  private text: string;
}

Спасибо

Хунбо Мяо
источник
Чтобы быть простым, частная функция может использоваться только в компоненте. Невозможно получить доступ к частной функции из другого компонента. Предположим, что в сервисе, если функция объявлена ​​частной, то к ней нельзя получить доступ из любого другого компонента.
Кевин

Ответы:

202

В ответ на этот вопрос есть что сказать, это первые мысли, которые пришли мне в голову:

Прежде всего, имейте в виду, что privateэто конструкция только во время компиляции - она ​​не может быть применена во время выполнения (см. Здесь и здесь для соответствующего обсуждения). Таким образом, пожалуйста, избавьтесь от любых представлений о том, privateчто это может быть полезно в целях безопасности. Дело не в этом.

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

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

Все это применимо к Typescript в целом. В частности, в Angular есть определенно допустимые варианты использования общедоступных членов в классах компонентов: например, при реализации шаблона контейнер / компонент (он же умный / тупой ) с «тупыми» дочерними элементами, вводящими «умных» родителей посредством внедрения конструктора, Чрезвычайно важно сообщить о своем намерении относительно того, какие члены родителя должны и не должны касаться детей: в противном случае не удивляйтесь, когда вы поймаете, что эти тупые дети дурачатся в винном шкафу своих родителей.

Итак, мой ответ на ваш вопрос:

должен ли я всегда добавлять приват для всех, как показано ниже?

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

Дрю Мур
источник
5
Спасибо за объяснение. Но, возможно, я ошибаюсь: я понимаю, что большую часть времени свойства и методы должны быть закрытыми (= "только для этого компонента"). Таким образом, ответ должен быть «ДА по умолчанию, если парню не нужно открывать свойство / метод извне». Нет? Зачем завершать свое объяснение ответом «нет» (что звучит как «никогда»)?
M'sieur Toph '21
1
Я написал руководство по angular 2, и я не понял, когда мне следует использовать public. Существует множество вариантов взаимодействия компонентов: angular.io/docs/ts/latest/cookbook/… Возможно, нам следует использовать public только для свойств и методов, определенных через Input Output. Но я не уверен.
Руслан Боровок
Обычно мне приходится использовать «public», когда я объявляю в конструкторе свойство, которое не используется внутри класса, но используется снаружи (то есть внутри шаблона или другого компонента).
tuliomarchetto
18

@drewmoore дает хороший ответ в том смысле, что частный / публичный сводится к намерению. Но есть еще несколько вещей, которые следует учитывать при использовании введенных частных значений:

  • И машинописный текст ( noUnusedLocals ), и tslint ( no-unused-variable ) будут сообщать об ошибках, если вы используете @Import() private foo, или constructor(private foo) {}, и используете только fooв своем шаблоне
  • AOT не будет работать :

Если мы хотим генерировать TypeScript как результат процесса компиляции AoT, мы должны убедиться, что мы получаем доступ только к общедоступным полям в шаблонах наших компонентов **

Лукас
источник
Что касается вашего первого замечания: эти ошибки не имеют ничего общего с тем, что член является частным или публичным, они просто указывают на то, что он не используется. Ваши вторые два пункта были бы действительны, если бы вопрос касался ссылки на частные члены в шаблонах , но это не так. Смотрите здесь вопрос , который
обратил МУР
@drewmoore, вы правы, и я понимаю, что они указывают, что они не используются. Однако общедоступные переменные могут использоваться извне, поэтому это предупреждение никогда не сработает . Что касается самих вопросов «Есть ли какой-либо вариант использования, когда они являются общедоступными в компоненте?», Я считаю, что мои второй и третий пункты по крайней мере указывают на вариант использования, когда они являются общедоступными , в частности, когда вы хотите использовать их в шаблоне. (как указано в цитируемом тексте).
Лукас