구성 요소로서의 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> ....

이 작업을 어떻게 할 수 있습니까?

답변:


111

기존 테이블 요소를 선택기로 사용

테이블 요소는 <table-line>요소를 자식으로 허용하지 않으며 브라우저 는 요소를 찾으면 제거합니다. 구성 요소로 래핑하고 허용 된 <tr>태그를 계속 사용할 수 있습니다. "tr"선택기로 사용하십시오 .

사용 <template>

<template>허용되어야하지만 아직 모든 브라우저에서 작동하지는 않습니다. Angular2는 실제로 <template>DOM에 요소를 추가하지 않고 내부적으로 만 처리하므로 Angular2를 사용하는 모든 브라우저에서도 사용할 수 있습니다.

속성 선택자

또 다른 방법은 속성 선택기를 사용하는 것입니다.

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

같이 사용

<tr my-tr>

그래서 저는 selector = 'tr'로 TableItemComponent를 만들 것입니다. 그러나 다른 문제에 대해 다른 장소에서 '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 문제)에서 피할 수없는 것 같습니다.
Rob

1
요소 선택기가 훨씬 더 일반적이므로 기본값이어야한다는 점을 제외하면 단점이 없다고 확신합니다. 테이블 요소 <li>또는 이와 유사한 유효한 경우가 있으면 사용 하지 않는 이유를 알 수 없습니다.
Günter Zöchbauer

2
내 컴포넌트 선택기가 tr [line-item]을 사용하도록하는 것은 작동했고 tslint가 불평하는 Angular Style 가이드 규칙 STYLE 05-03을 준수합니다.
CM

31

예제가 매우 유용하다는 것을 알았지 만 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과 작품 잘.
Tito Leiva 2018

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) 플 런커 .


루트 태그없이 구성 요소를 렌더링 할 수 있습니까? Knockout.js의 <!-/ ko->와 같은 것입니다.
Ssss apr


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'.
Vukasin

작동하게하려면 선택기에 []를 추가해야합니다. 잊지 마세요.
AFetter

6

구성 요소 스타일에 '디스플레이 : 콘텐츠'를 추가하는 것은 저에게 효과적이었습니다.

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

안녕하세요 @Rajan, 팁 주셔서 감사합니다. 방금 어떻게 contents작동 하는지 알아 냈기 때문에 잘못된 가정에 근거한 정보를 넣고 싶지 않았어요 ... 제가 이해 한대로 설명을 추가했지만, 누군가 오류가 있다는 것을 알아 차리면 부담없이 지적 해주세요 ^ ^. 또한 사람들이 더 자세히 조사 할 수 있도록 링크를 추가했습니다. 한 가지는 IE11에서 작동하지 않는다고 말했지만 IE 11.657.18362.0에서 시도해 보았지만 제대로 작동했습니다 (하지만 각도를 사용하면 어딘가에 폴리 필이있을 수 있으므로 다른 환경에서는 100 % 보장하지 않습니다.)
Ruben Negredo

아주 좋은 대답입니다. IMO 이것은 받아 들여 져야합니다.
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{}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.