Это не дубликат ответа этого поста и не (правильное) объяснение того, что делает оператор звездочки здесь. Однако он основан на них.
Суть в том, что *ngBeep — это удобный, синтаксически уверенный и краткий способ выражения [ngBeep]. Однако в своем коде я использовал следующие выражения. Они делают одно и то же (насколько я могу судить) и ведут себя так, как и ожидалось.
<div *ngFor = "let item of [1,2,3]">
#{{item}}
<ng-container *ngTemplateOutlet = "content"></ng-container>
<ng-container [ngTemplateOutlet] = "content"></ng-container>
</div>
Ну... технически говоря, первое короче второго. Однако кажется глупым вводить совершенно новый оператор для удаления одного символа. Конечно, для других директив сохраненных символов/строк может быть гораздо больше, чем в приведенном выше конкретном примере.
Являются ли эти две контейнерные линии абсолютно эквивалентными (в данном патологическом случае)? Если нет, то чем они отличаются (под капотом)?





Эти две строки в вопросе эквивалентны?
Да.
Однако звездный синтаксис-сахар — это нечто большее. Во-первых, он оборачивает свое содержимое в ng-template (потому что вам нужно визуализировать этот шаблон при каком-то условии или, возможно, несколько раз, в зависимости от директивы). Это означает следующий код.
<span *ngIf = "show">text</span>
// equivalent
<ng-template [ngIf] = "show"><span>text</span></ng-template>
Во-вторых, он добавляет префикс для передаваемых полей, как показано ниже.
<ng-container *ngTemplateOutlet = "content; context: {var1: 123}">
</ng-container>
// ...and its equivalent
<ng-container [ngTemplateOutlet] = "content"
[ngTemplateOutletContext] = "{var1: 123}">
</ng-container>
Затем она ссылается на данные, которые предоставляет сама директива, в контексте, что более удобно, вот так.
<li *ngFor = "let item of items; index as i; first as isFirst; trackBy: trackByFn">...</li>
// equivalent
<ng-template ngFor let-item [ngForOf] = "items"
let-i = "index" let-isFirst = "first"
[ngForTrackBy] = "trackByFn">
<li>...</li>
</ng-template>
Нет... они не эквивалентны. Вы сами это объяснили. Я собирался понизить голос сразу после прочтения «Да». Но потом... Я все это прочитал, вы правы во всем своем ответе, за исключением той части «Да», которая меня сбивает с толку TL;DR. Правильные эквиваленты — это те, которые вы указали в своих примерах. Пожалуйста, просто исправьте первую часть своего ответа. В настоящее время в вашем ответе говорится: «Да, они эквивалентны, однако... нет, правильная эквивалентность - это все это...»
Я бы сказал, что <ng-container *ngTemplateOutlet" это еще и сахар для <ng-template [ngTemplateOutlet]><ng-container>...
Как вы можете видеть в исходном коде, использование *ngTemplateOutlet и [ngTemplateOutlet] не отличается, поскольку вы используете один и тот же класс.
Глядя на класс, вы можете увидеть это свойство:
@Input() public ngTemplateOutletContext: C | null = null;
Это означает, что следующие фрагменты почти эквивалентны:
<ng-container *ngTemplateOutlet = "content; context: myContextObj">
</ng-container>
<ng-container [ngTemplateOutlet] = "content"
[ngTemplateOutletContext] = "myContextObj">
</ng-container>
Фактически, используя сокращение *, вы можете указать входные данные, если за Directive следует точка с запятой.
Это справедливо для каждой структурной директивы : их можно использовать со ссылкой на свою selector или с структурной директивой *, сокращенно.
Что происходит под капотом, чтобы прежние фрагменты отличались?
Если вы посмотрите документацию, на которую я ссылаюсь, вы увидите, что при использовании сокращения * Angular обернет ваш элемент в ng-template и применит к нему директиву с селектором:
Из документации эти два шаблона эквивалентны:
<div class = "name" *ngIf = "hero">{{hero.name}}</div>
<ng-template [ngIf] = "hero">
<div class = "name">{{hero.name}}</div>
</ng-template>
Вы видите, что с помощью этих мощных инструментов сложность может быстро возрастать, поэтому Angular не допускает использование двух структурных директив для одного и того же элемента, потому что было бы невозможно заранее узнать, какая директива должна иметь приоритет.
Возможно, это единственное различие между двумя подходами, которое может повлиять на опыт разработчика: если вы хотите использовать ngTemplateOutlet и другую структурную директиву, у вас есть 2 возможности:
ng-container и используйте структурную директиву в двух разных элементах.*// Using 2 "*" shorthand in the same element: the code won't compile
<ng-container *ngTemplateOutlet = "content" *ngIf = "true">
</ng-container>
// Approach 1, the code will compile
<ng-container *ngIf = "true">
<ng-container *ngTemplateOutlet = "content">
</ng-container>
</ng-container>
// Approach 2, the code will compile
<ng-container [ngTemplateOutlet] = "content" *ngIf = "true">
</ng-container>
Не могли бы вы подробнее рассказать о различных возможностях использования структурных директив?
Конечно! Я понял, что вопрос не касается использования оператора *, сейчас я отредактировал ответ.
Да, вы тоже правильно задали вопрос с первого раза. Я просто хотел некоторых подробностей, чтобы подтвердить, что я понял это полностью, а также «будущие поколения», видящие ответ, которые, возможно, находятся в еще большем замешательстве, чем я. Я уже принял другой ответ как ответ, но за большие усилия я поставлю вам +1 и также добавлю награду. Ты заслуживаешь это.
Исправление в части вознаграждения. Кажется, я не могу. Нет кнопки, позволяющей создать округ (даже не сообщая мне, что он имеет право на это через определенный период времени). Может быть, это потому, что у меня уже есть один активный...? Не уверен.
Спасибо! Думаю, нам придется подождать пару дней. «Баунти можно начать за вопрос через два дня после того, как вопрос был задан».. Если вы считаете, что этот ответ заслуживает видимости, я бы попросил вас проголосовать за него, если не пометить его как принятый ответ, чтобы он не потерял видимость для будущих читателей.
Странно... Я получил электронное письмо, в котором говорилось: «Теперь вы сможете назначить награду, если хотите», но я не вижу этого нигде в вопросе. Есть ли у Stacky искусственный интеллект, который напоминает людям о необходимости выражать признательность на основе комментариев? Отличная функция, но все равно... чушь?! :D
Комментарий написал с мобильного, возможно, я его по ошибке удалил, потому что тоже не вижу, извините :D
Отличный ответ! Я взял на себя смелость отшлифовать его лингвистически — надеюсь, вы не против. Техническая сторона здесь идеальна, и я ясно понимаю, как мое недавнее невежество привело меня в замешательство. Спасибо друг.