21

シナリオ

私が多くの店舗を持つ大企業のオーナーだとしましょう。社内での役割 (組織内の場所) に応じて、データへのアクセス権が異なります。さまざまなモジュールがあり、この特定の質問には、アクセス権を持つユーザーが毎日のコストと売上を確認できるモジュールがあります。(それが合法であるかどうか...気にしないでください。これは単なる例です。)

これにより、ユーザーはバックエンド (Java アプリケーション) から REST API を介してすべてのデータを取得し、ユーザーがアクセスできるすべてのストアのすべてのデータを取得します。ユーザーは、さまざまなフィルターの組み合わせによって、データをフィルター処理できる必要があります。私の質問に最も関連するのは、日ごとの日付間隔です。

さまざまなレベルのデータを示すグラフがいくつかあり、その下にはマルチレベルのテーブルが必要なテーブル領域があるため、私の質問です。

ここまで完了

  1. 最初に、アコーディオン グループ レベルのストアを持つアコーディオンを作成し、次に、アコーディオン本体内のテーブル内の次のレベルのデータを作成しました。(現時点ではハードコードされたデータのみです。) ここでの問題は、対応する見出しが文字列であることであり、いくつかの議論の後、見出しはテーブル内のデータの一部で構成されるため、これは適切な解決策ではないと感じました。別々の列。したがって、折りたたまれたときに (アコーディオンの見出し間で) さまざまな「ストア」に水平方向に一致するように見出しデータを「列化」することは困難です (もちろん、1 つまたは複数のアコーディオンが展開されている場合はさらに面倒です)。
  2. アコーディオンをテーブルと ng-repeat に置き換えました。比喩的な API からのデータと JSON データの両方を最初のテーブル レベルに正常に入力し、見出しに対して i18next を機能させました。

JSON

{ 
"metadata":{
    "storesInTotal":"25",
    "storesInRepresentation":"2"
},
"storedata":[
    { 
        "store" : {
            "storeId" : "1000",
            "storeName" : "Store 1",
            "storePhone" : "+46 31 1234567",
            "storeAddress": "Some street 1",
            "storeCity" : "Gothenburg"
        },
        "data" : {
            "startDate" : "2013-07-01",
            "endDate" : "2013-07-02",
            "costTotal" : "100000",
            "salesTotal" : "150000",
            "revenueTotal" : "50000",
            "averageEmployees" : "3.5",
            "averageEmployeesHours" : "26.5",
            "dayData" : [
                { 
                    "date" : "2013-07-01",
                    "cost" : "25000",
                    "sales" : "15000",
                    "revenue" : "4000",
                    "employees" : "3",
                    "employeesHoursSum" : "24"
                },
                {
                    "date" : "2013-07-02",
                    "cost" : "25000",
                    "sales" : "16000",
                    "revenue" : "5000",
                    "employees" : "4",
                    "employeesHoursSum" : "29"
                }
            ]
        }
    },
    {
        "store" : {
            "storeId" : "2000",
            "storeName" : "Store 2",
            "storePhone" : "+46 8 9876543",
            "storeAddress": "Big street 100",
            "storeCity" : "Stockholm"
        },
        "data" : {
            "startDate" : "2013-07-01",
            "endDate" : "2013-07-02",
            "costTotal" : "170000",
            "salesTotal" : "250000",
            "revenueTotal" : "80000",
            "averageEmployees" : "4.5",
            "averageEmployeesHours" : "35",
            "dayData" : [
                { 
                    "date" : "2013-07-01",
                    "cost" : "85000",
                    "sales" : "120000",
                    "revenue" : "35000",
                    "employees" : "5",
                    "employeesHoursSum" : "38"
                },
                {
                    "date" : "2013-07-02",
                    "cost" : "85000",
                    "sales" : "130000",
                    "revenue" : "45000",
                    "employees" : "4",
                    "employeesHoursSum" : "32"
                }
            ]
        }
    }
],
"_links":{
    "self":{
        "href":"/storedata/between/2013-07-01/2013-07-02"
    }
}
}

視覚的な例 - JSFiddle

結果フレームの左上隅の値を確認します。たとえば、ストア ID 2000、3000、3000 の行をクリックして、値がどのように変化するかを確認してください。 私のJSFiddleの現在の更新

欲しかった機能

行がクリックされると (JSFiddle に示されているように)、ディレクティブまたは何かがトリガーされて、クリックされたストアの基礎となるデータ (dayData) をフェッチし、日付間隔のすべての日を表示する必要があります。つまり、行を展開し、クリックした行の下に新しいテーブルを含めます。これも ng-repeat を使用して、既存のものと同様に表示されるすべてのデータをインラインで取得する必要があります。

質問

したがって、クリックした行から $index と特定のデータを取得する機能を既に持っています。「行がクリックされたときのデータ」を取得し、クリックされた行の下の表に表示するには、どのようなディレクティブまたはその他のソリューションが必要ですか?

各ストアと多くのストアに多くの dayData が存在する可能性があるため、常に DOM に入れたいわけではありません。(そして、後でページネーションを使用しますが、それでもDOMでは常にではありません。)これは、行をクリックしたとき、および同じまたは別のREMOVEをクリックしたときに、以前にクリックしたものから追加できる必要があることを意味します。


編集

新しく更新された JSFiddle

4

3 に答える 3

26

要件は、DOM をすべての第 2 レベルのテーブルで埋めないことでした。私はそれに対する解決策を思いつきました。

最初にカスタム ディレクティブを作成しようとしましたが、適切な場所 (クリックされた行の下) に行を挿入し、ヘッダーを含む第 2 レベルのテーブルを作成しましたが、ng-repeat を使用して行を入力できませんでした。

完全に機能する解決策が見つからなかったので、ng-show を使用して既に作成したものに戻り、そのような解決策を探しました...そして存在します。ng-show/ng-hide を使用する代わりに、Angular には ng-switch と呼ばれるディレクティブがあります。

レベル1で

<tbody data-ng-repeat="storedata in storeDataModel.storedata" 
       data-ng-switch on="dayDataCollapse[$index]">

...そして、2 番目のレベル、つまり 2 番目の tr

<tr data-ng-switch-when="true">

、2 番目のレベルの ng-repeat があります。

これが新しいJSFiddleです。

要素を調べると、「折りたたまれた」レベル 2 テーブルごとにコメント プレースホルダーがあることがわかります。


更新 (2014-09-29)

レベル 3 の展開/折りたたみも要求されたので、ここに新しいJSFIDDLEがあります。

ノート!- このソリューションは、すべての情報を常に DOM に保持します。つまり、要求に応じて情報を追加する場所の表記のみを追加した以前のソリューションとは異なります。

(ただし、友人の Axel が私のフォークをフォークして機能を追加したため、これを信用することはできません。)

于 2013-08-07T23:27:40.520 に答える
4

より良い解決策は、tbody で ng-repeat を使用するのではなく、tr 要素で ng-repeat-start および ng-repeat-end ディレクティブを使用することだと思います (この場合、複数の tbody を正当化することはできません)。

ここを見てください:

PLNKR

<tr ng-repeat-start="person in people">
  <td>
    <button ng-if="person.expanded" ng-click="person.expanded = false"></button>
    <button ng-if="!person.expanded" ng-click="person.expanded = true"></button>
  </td>
  <td>{{person.name}}</td>
  <td>{{person.gender}}</td>
</tr>
<tr ng-if="person.expanded" ng-repeat-end="">
  <td colspan="3">{{person.details}}</td>
</tr>
于 2016-07-27T13:59:08.263 に答える
0

コメントするにはまだ十分な評判がないので、私が遭遇した追加の機能の問題について回答をフォローアップしています. 私は、DOM が第 2 レベルのデータ/テーブルで表示されるまで汚染されず、すべてが完全に機能していることを本当に気に入っているので、Pixic の構造をうまく使用しました。

最上位テーブルの動的ソートを許可するように求められるまで。問題ありません。最上位のテーブルを並べ替えることができます。問題は、第 2 レベルのテーブル (つまり hidden ) を同期させて、トップ レベルのテーブルと同じように「移動」させる方法を考え出すことができなかったことです。これは表示のみの問題です。基になるデータは最上位レベルに適切に関連付けられていますが、第 2 レベルのテーブルが親行で再ソートされないため、元の「インデックス付き」行が表示されるため、表示が乱れます。

私が思いつくことができる唯一のことは、行を展開するときにコントローラーから第 2 レベルの html を動的に挿入することですが、他の誰かが他のアイデアを持っているかどうか疑問に思っています。私は ng-repeat-start と ng-repeat-end を試しました (tbody 内のすべてのアイテムを一緒に保持する必要があると考えているすべての要素を含めるための非表示の 3 番目の tr タグと、非表示の tbody で) を試しましたが、うまくいきませんでした。

編集: 要求に応じて、別の質問を開始しました:マルチレベルテーブル(クリックすると別のテーブル内)およびトップレベルテーブルの動的ソート

于 2018-02-14T19:35:04.870 に答える