Рядки таблиці Angular2 як компонент


99

Я експериментую з angular2 2.0.0-beta.0

У мене є таблиця, і вміст рядка генерується angular2 таким чином:

    <table>
        <tr *ngFor="#line of data">
            .... content ....
        </tr>
    </table>

Зараз це працює, і я хочу інкапсулювати вміст у компонент "рядок таблиці".

    <table>
        <table-line *ngFor="#line of data" [data]="line">
        </table-line>
    </table>

А в компоненті шаблон має вміст <tr> <td>.

Але зараз стіл більше не працює. Це означає, що вміст більше не відображається у стовпцях. У браузері інспектор показує мені, що елементи DOM виглядають так:

    <table>
        <table-line ...>
            <tbody>
                <tr> ....

Як я можу зробити цю роботу?

Відповіді:


110

використовувати існуючі елементи таблиці як селектор

Елемент таблиці не дозволяє використовувати <table-line>елементи як дочірні, і браузер просто видаляє їх, коли їх знаходить. Ви можете загорнути його в компонент і при цьому використовувати дозволений <tr>тег. Просто використовуйте "tr"як селектор.

використовуючи <template>

<template>слід також дозволити, але поки не працює у всіх браузерах. Angular2 насправді ніколи не додає <template>елемент до DOM, а лише обробляє їх внутрішньо, тому це також можна використовувати у всіх браузерах з Angular2.

Вибір атрибутів

Інший спосіб - використовувати селектори атрибутів

@Component({
  selector: '[my-tr]',
  ...
})

використовуватися як

<tr my-tr>

Тож я б створив мій TableItemComponent із селектором = 'tr'. Але як можна використовувати "tr" в інших місцях для різних питань?
fbenoit

6
Якщо батьківський компонент включає ваш власний trтег, він буде використовуватися, інакше має місце поведінка браузера за замовчуванням. Ви також можете додавати атрибути або класи до селектора компонентів, наприклад <tr line-item>за допомогою селектора компонентів "tr[line-item] "або <tr class="line-item">селектора компонентів tr.line-item. Таким чином ви маєте повний контроль. Я ще нічого з цього не пробував у Angular2, але я впевнений, що це працює.
Günter Zöchbauer

5
Чи є в цьому реальний недолік? Це чудово працює, проте налаштування за замовчуванням tslintспрямовують мене до керівництва стилем, яке рекомендує проти цього. Мені не подобається відключати рекомендовані правила підключення, але, наскільки я можу зрозуміти, це здається досить довільним правилом стилю і неминучим у деяких ситуаціях (наприклад, проблема OP)
Роб

1
Я майже впевнений, що недоліків немає, за винятком того, що селектори елементів є набагато більш поширеними і тому повинні бути типовими. Якщо є дійсний регістр, такий як елементи таблиці <li>або подібний, я не бачу жодної причини, чому б його не використовувати.
Гюнтер Цохбауер,

2
Робота мого селектора компонентів з використанням tr [рядок-позиція] спрацювала і відповідає правилу керівництва Angular Style STYLE 05-03, на яке скаржиться tslint.
CM

30

Я знайшов приклад дуже корисним, але він не працював у збірці 2,2.3, тому після довгих подряпин в голові змусив його знову працювати з кількома невеликими змінами.

import {Component, Input} from '@angular/core'

@Component({
  selector: "[my-tr]",
  template: `<td *ngFor='let item of row'>{{item}}</td>`    
})
export class MyTrComponent {
  @Input("line") row:any;
}

@Component({
  selector: "my-app",
  template: `<h1>{{title}}</h1>
  <table>
    <tr  *ngFor="let line of data" my-tr [line]="line"></tr>
  </table>`

})
export class AppComponent {

  title = "Angular 2 - tr attribute selector!";
  data = [ [1,2,3], [11, 12, 13] ];
  constructor() { console.clear(); }
}

1
Чудова відповідь. Мені просто довелося додати MyTrComponentдо app.module.tsі працює нормально.
Тіто Лейва

26

Ось приклад використання компонента з селектором атрибутів:

import {Component, Input} from '@angular/core';
@Component({
  selector: '[myTr]',
  template: `<td *ngFor="let item of row">{{item}}</td>`
})
export class MyTrComponent {
  @Input('myTr') row;
}
@Component({
  selector: 'my-app',
  template: `{{title}}
  <table>
    <tr *ngFor="let line of data" [myTr]="line"></tr>
  </table>
  `
})
export class AppComponent {
  title = "Angular 2 - tr attribute selector";
  data = [ [1,2,3], [11, 12, 13] ];
}

Вихід:

1   2   3
11  12  13

Звичайно, шаблон у MyTrComponent був би більш залучений, але ви зрозуміли ідею.

Старий (бета.0) плюнкер .


Чи можна відобразити ng-компонент без кореневого тегу? Щось на зразок <! - / ko -> у Knockout.js.
Ssss


14
Це взагалі не працює (спробували з angular 2.3). Error: Uncaught (in promise): Error: Template parse errors: Can't bind to 'myTr' since it isn't a known property of 'tr'.
Виявлено

Щоб це працювало, вам потрібно додати [] на Selector. Не забувайте про це.
AFetter

6

Додавання 'display: contents' до стилю компонента, який мені розроблено.

CSS:

.table-line {
    display: contents;
}

HTML:

<table>
    <table-line class="table-line" [data]="line">
    </table-line>
</table>

Чому це працює?

Під час інстанціювання компонента angular (після компіляції) обертає вміст компонента в DOM наступним чином:

<table>
    <table-line>
        <tr></tr>
    </table-line>
</table>

Але для того, щоб таблиця відображалася належним чином, trтеги не можна нічим обернути.

Отже, ми додаємо display: contentsдо цього нового елемента. Як я розумію, це робить для того, щоб сказати досліднику, що цей тег не повинен відображатися, і відображати внутрішній вміст так, ніби не було обгортання. Отже, хоча тег все ще існує, він візуально не впливає на таблицю, і trтеги обробляються так, ніби вони є прямими дочірніми елементамиtable тегу.

Якщо ви хочете дізнатися далі про те, як працює вміст: https://bitsofco.de/how-display-contents-works/


1
Коли це можливо, докладіть зусиль, щоб надати додаткові пояснення замість просто коду. Такі відповіді, як правило, є більш корисними, оскільки вони допомагають членам спільноти та особливо новим розробникам краще зрозуміти аргументи рішення та можуть допомогти уникнути необхідності вирішувати подальші питання.
Раджан

Привіт @Rajan, дякую за підказку. Я щойно виявив, як це contentsпрацює, тому не хотів розміщувати там інформацію на основі хибних припущень ... Я додав пояснення, наскільки я розумію, але якщо хтось помітить, що в ньому є помилка, будь ласка, вкажіть це ^ ^. Я також додав посилання, щоб люди могли розслідувати далі ... Одне я помітив, хоча там сказано, що це не працює на IE11, я спробував це на IE 11.657.18362.0, і воно спрацювало нормально (але, оскільки я використовуючи кутовий, десь може бути поліфіл, тому я б не гарантував його на 100% в інших середовищах)
Рубен Негредо

Дуже хороша відповідь. ІМО це слід прийняти.
adamsfamily

-3

спробуйте це

@Component({
    selecctor: 'parent-selector',
    template: '<table><body><tra></tra></body></table>'
    styles: 'tra{ display:table-row; box-sizing:inherit; }'
})
export class ParentComponent{
}

@Component({
    selecctor: 'parent-selector',
    template: '<td>Name</td>Date<td></td><td>Stackoverflow</td>'
})
export class ChildComponent{}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.