Опираясь на мою предыдущую часть, в которой перечислены некоторые из моих первоначальных реакций на Angular 2 после перехода с проекта React, у меня есть некоторые мысли о том, как эти фреймворки внедряют разметку в DOM (или shadow-DOM) и эффекты .
Пример использования
Вот пример использования. У меня есть массив имен пользователей, которые я хочу отобразить, и я собираюсь отобразить их с помощью двух компонентов. Первый — это в основном <ul>
, но здесь это умный компонент, который будет вручную извлекать данные (как и откуда не имеет значения). Дочерний компонент будет простым компонентом, в основном <li>
, который просто отображает имя. Однако я буду использовать элементы <div>
, чтобы для простоты уменьшить размер объявлений CSS.
// the data const usernames = ["Donald", "Barack", "George", "William"] // the basic markup structure <div class="list"> <div class="item">Donald</div> <div class="item">Barack</div> <div class="item">George</div> <div class="item">William</div> </div> // the basic styles .list { display: flex; flex-direction: row; flex-wrap: wrap; } .item { flex: 0 0 25%; }
Реагировать
Базовая реализация React будет выглядеть так:
const Item = ({name}) => <div style={{'flex': '0 0 25%'}}>{name}</div> class List extends Component { render(){ const usernames = ["Donald", "Barack", "George", "William"] const listStyle = { 'display': 'flex', 'flex-direction': 'row', 'flex-wrap': 'wrap' } return ( <div style={listStyle}> {usernames.map(item => <Item name={item} />)} </div> ) } }
Результирующая разметка будет точно соответствовать ожидаемой разметке (за исключением объявлений стилей вместо классов CSS), потому что React полностью заменяет дочерние компоненты структурой, возвращаемой return()
подкомпонента.
Очень просто.
Угловой 2
Объяснить, как Angular 2 справляется с этим, будет сложнее. Во-первых, мне придется включить оба компонента в содержащий их модуль, что я здесь не демонстрирую. Я также исключаю проверки TypeScript.
Во-первых, смарт-компонент.
@Component({ selector: 'my-list', template: ` <style> .list { display: flex; flex-direction: row; flex-wrap: wrap; } </style> <div class="list"> <my-item *ngFor="let item of items" [name]="item"></my-item> </div> ` }) export class ListComponent { items = ["Donald", "Barack", "George", "William"]; constructor(){ } }
И тупой.
@Component({ selector: 'my-item', template: ` <style> .item { flex: 0 0 25%; } </style> <div class="item">{{name}}</div> ` }) export class ItemComponent { @Input() name: string; constructor(){ } }
Результирующая разметка (в Chrome Inspector) будет выглядеть так:
<project-card-list> <div class="list"> <my-item> <div class="item">Donald</div> <my-item> <my-item> <div class="item">Barack</div> <my-item> <my-item> <div class="item">George</div> <my-item> <my-item> <div class="item">William</div> <my-item> </div> </project-card-list>
Как видите, подкомпонент заключен в тег, соответствующий его селектору. Меня это беспокоит по нескольким причинам:
- Макет flex-box кажется, по-прежнему работает, даже несмотря на наличие промежуточного тега. Я понятия не имею, почему именно (странность теневого DOM?). О том, как я ожидаю, что это будет работать, см. в этом JSBin. С одной стороны, это, вероятно, уместно, потому что это то, что я имел в виду, но с другой стороны, я не могу понять, почему тег
<my-item>
, похоже, игнорируется при расчете макета, и я не могу найти никакой документации по этому поводу. Если я установлюmy-item
tag наdisplay: flex
, он сломается, но не иначе. Кто-нибудь может это объяснить? - Как и все остальное в Angular и React — код всегда кажется в два раза более многословным, и я ненавижу, ненавижу, ненавижу этот синтаксис:
*ngFor="let item of items"
по сравнению с чистым.map()
React. - Есть и другие странности, с которыми вы можете столкнуться, если избавитесь от оболочки, содержащей
<div class="item">
, в дочернем компоненте и попытаетесь напрямую стилизовать тегmy-item
. Во-первых, этот класс не будет затронут каким-либо CSS, который вы укажете в дочернем компоненте, и хотя я думаю, что вы можете перейти вверх по цепочке областей видимости (может быть,:host
?), это кажется действительно уродливым и похоже на то, чего лучше избегать. .