コンポーネントとしての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要素では、<table-line>要素を子として使用することはできません。ブラウザは、要素を見つけたときにそれらを削除するだけです。これをコンポーネントにラップしても、許可された<tr>タグを使用できます。"tr"セレクタとして使用するだけです。

を使用して <template>

<template>許可する必要がありますが、すべてのブラウザでまだ機能しません。Angular2は実際には<template>要素をDOMに追加することはなく、内部でのみ処理するため、Angular2を備えたすべてのブラウザーで使用できます。

属性セレクター

別の方法は、属性セレクターを使用することです

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

のように使用する

<tr my-tr>

したがって、セレクター= 'tr'を使用してTableItemComponentを作成します。しかし、別の問題で他の場所で「tr」をどのように使用できますか?
fbenoit

6
親コンポーネントにカスタムtrタグが含まれている場合はそれが使用されます。それ以外の場合は、デフォルトのブラウザ動作が実行されます。また、のようなあなたのコンポーネントセレクタに属性やクラスを追加することができ<tr line-item>コンポーネントセレクタ付き"tr[line-item] "または<tr class="line-item">コンポーネントセレクタ付きtr.line-item。このようにして、完全に制御できます。私はまだAngular2でこれを試したことはありませんが、これがうまくいくと確信しています。
ギュンターZöchbauer

5
これには実際の欠点はありますか?それはのためしかし、デフォルトの設定、正常に動作tslintへの直接私のスタイルガイド推奨に対してこれ。推奨されるリンティングルールをオフにするのは嫌いですが、私の知る限り、かなり恣意的なスタイルのルールであり、状況によっては避けられないようです(OPの問題など)
Rob

1
要素セレクターがより一般的であり、したがってデフォルトである必要があることを除いて、欠点はないと確信しています。テーブル要素などの有効なケースがある場合<li>、それを使用しない理由はわかりません。
ギュンターZöchbauer

2
コンポーネントセレクターにtr [line-item]を使用させることは機能し、tslintが不満を言うAngular StyleガイドルールSTYLE 05-03に準拠しています。
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
すばらしい答えです。私は追加する必要がありましたMyTrComponentapp.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のテンプレートの方が複雑ですが、アイデアはわかります。

古い(beta.0)プランカー


ルートタグなしでngコンポーネントをレンダリングすることは可能ですか?Knockout.jsの<!-/ ko->のようなもの。
Ssss

@ PashaPasha、stackoverflow.com
Mark Rajcok

14
これはまったく機能しません(角度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

コンポーネントのスタイルに「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動作の仕組みを発見したばかりなので、誤った仮定に基づいて情報を表示したくありませんでした...理解しているときに説明を追加しましたが、誰かがエラーに気づいた場合は、遠慮なく指摘してください^ ^。私はまた、人々がさらに調査できるようにリンクを追加しました...私が気づいたことの1つは、これはIE11では機能しないと述べていますが、IE 11.657.18362.0で試してみましたが、正常に機能しました(ただし、アンギュラーを使用すると、ポリフィルがどこかにある可能性があるため、他の環境では100%保証されません)
ルーベンネグレド

とても良い答えです。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.