1

タブをクリックすると、単一のページに複数の angularjs ディレクティブを表示する必要があります。これは、c3 チャート ディレクティブと ng グリッド ディレクティブの組み合わせである可能性があります。コントローラーでこれらすべての関連パラメーターを使用してモデルを準備し、テンプレートを作成してから、コントローラー自体でコンパイルします。これは完全に正常に機能しています。コントローラーで DOM 操作を行うのは良い方法ではないことに気付いたので、カスタム ディレクティブでそれを実行しようとしています。

このディレクティブは、次の機能をサポートする必要があります。

  1. テンプレートは、C3 チャート ディレクティブの組み合わせである必要があります。
  2. テンプレートには、c3 チャート ディレクティブと共に Angularjs ng Grid ディレクティブも含めることができます。
  3. 将来的には、C3 chart および ng grid ディレクティブと共に Good Map ディレクティブも使用したいと考えています。
  4. また、これらのディレクティブの一部は、カスタム ドロップダウンでサポートする必要があります。

今のところ、完全に正常に動作しているコントローラーで次のコードを使用しました。

   var template = '<div class= "chartsDiv">';

    var dashletteId = 0;
    var dashletterName = "chart";
    var chartName = "";

    for (var dashVar = 0; dashVar < data.tabDetails.length; dashVar++) {
        dashletteId = data.tabDetails[dashVar].dashletteId; // Added
        dashletterName = data.tabDetails[dashVar].dashletteName;
        var axisType = data.tabDetails[dashVar].axisType;
        var dataType = data.tabDetails[dashVar].dataType;

        chartName = "chart" + eachTab.tabName.replace(/ +/g, "") + dashletteId ;

        $scope[chartName] = {};


        if (axisType == "timeseries") {

            var xticksClassiffication = data.tabDetails[dashVar].xticksClassification;
            var tickFormatFunction = {};               
            $scope[chartName] = {

                data: {
                    x: 'x',
                    columns: data.tabDetails[dashVar].columns,
                    type: data.tabDetails[dashVar].dataType
                },
                axis: {
                    x: {
                        type: data.tabDetails[dashVar].axisType,                          
                        tick: {
                            format: data.tabDetails[dashVar].xtickformat
                                // '%Y-%m-%d'

                        }
                    }
                },
                subchart: {
                    show: true
                }

            };

        }

        if (dashletteId == 7) {

            template += ' <div class="col"> <p class="graphtitle">' + dashletterName + '  </p> <span class="nullable">  <select ng-model="chartTypeSel" ng-options="eachChartType.name for eachChartType in chartTypeOptions" ng-change="transformChart(chartTypeSel, \'' + chartName + '\')"> </select> </span> <c3-simple id = "' + chartName + '" config="' + chartName + '"></c3-simple>  </div>'

        } else {

            template += ' <div class="col"> <p class="graphtitle">' + dashletterName + ' </p> <c3-simple id = "' + chartName + '" config="' + chartName + '"></c3-simple> </div>';
        }


    }

    template += ' </div>';
    angular.element(document.querySelectorAll('.snap-content')).append($compile(template)($scope));

簡単にするために、いくつかのサンプルコードのみを提供しました。dashletteId に基づいて、dashletteId に基づいてテンプレートを動的に作成するための特定の要件がいくつかあります。このコードはすべて完全に機能しています。今、私の目的は、このすべてのテンプレート形成とコンパイル コードをコントローラーからカスタム ディレクティブに移動することです。これに対する最善の解決策を探しています。

特定のユーザーが任意のタブをクリックすると、コンパイルのためにどのテンプレートを作成する必要があるかが事前定義されています。したがって、ng-init関数呼び出しまたはタブのクリック(つまり、選択)関数呼び出しのいずれかでそれを取得できます。

以下は、私の ng グリッド テンプレート形成のサンプル コードです。

if (axisType == "table") {

        var config = {
            9: {
                gridOptions: 'gridOptionsOne',
                data: 'dataOne',
                columnDefs: 'colDefsOne'
            },
            10: {
                gridOptions: 'gridOptionsTwo',
                data: 'dataTwo',
                columnDefs: 'colDefsTwo'
            },
            11: {
                gridOptions: 'gridOptionsThree',
                data: 'dataThree',
                columnDefs: 'colDefsThree'
            },
            18: {
                gridOptions: 'gridOptionsFour',
                data: 'dataFour',
                columnDefs: 'colDefsFour'
            }
        };

        $scope.getColumnDefs = function(columns) {
            var columnDefs = [];

            columnDefs.push({
                field: 'mode',
                displayName: 'Mode',
                enableCellEdit: true,
                width: '10%'
            });
            columnDefs.push({
                field: 'service',
                displayName: 'Service',
                enableCellEdit: true,
                width: '10%'
            });

            angular.forEach(columns, function(value, key) {
                columnDefs.push({
                    field: key,
                    displayName: value,
                    enableCellEdit: true,
                    width: '10%'
                })
            });

            return columnDefs;
        };

        if (dataType == "nggridcomplex") {

            $scope.serverResponse = {
                columns: data.tabDetails[dashVar].columns,
                data: data.tabDetails[dashVar].data

            };

            $scope[config[dashletteId].columnDefs] = $scope.serverResponse.columns;
            $scope[config[dashletteId].data] = $scope.serverResponse.data;

        } else {
            if (dashletteId == 18) {
                $scope.serverResponse = {
                    columns: data.tabDetails[dashVar].timespans[0], // This is for column headers.
                    data: data.tabDetails[dashVar].columns
                };

            } else {
                $scope.serverResponse = {
                    columns: data.tabDetails[dashVar].timespans[0], // This is for column headers.
                    data: data.tabDetails[dashVar].columns
                };
            }


            $scope[config[dashletteId].columnDefs] = $scope.getColumnDefs($scope.serverResponse.columns);
            $scope[config[dashletteId].data] = $scope.serverResponse.data;
        }

        $scope[config[dashletteId].gridOptions] = {
            data: config[dashletteId].data,
            showGroupPanel: true,
            jqueryUIDraggable: false,
            columnDefs: config[dashletteId].columnDefs
        };

        template += ' <div class="col"> <p class="graphtitle">' + dashletterName + ' </p> <div class="gridStyle" ng-grid="' + config[dashletteId].gridOptions + '"></div>';

    }

したがって、1 つのページに 4 つのディレクティブを表示する必要があります。ユーザーが事前に定義した選択に基づいて、3 つの c3 チャートと 1 つの ng Grid テーブル ディレクティブ、または 2 つの C3 チャートと 2 つの ng グリッド テーブルなどを表示する必要があります。

以下は、これにさらに取り組む前のカスタム ディレクティブの予備的なコードです。より良いアプローチのために、他のユーザーからの情報を取得することを考えました。ここで私のリンク関数では、タブのクリックまたは ng-init フェーズなどでコントローラーから動的に取得する必要があるテンプレートを使用します。

app.directive('customCharts', ['$compile', function($compile) {
    return {
        restrict: 'EA',
        scope: {
            chartName: '='
        },
        link: function(scope, element) {
            var template = ' <div class="col"> <p class="graphtitle">' + dashletterName + ' </p> <c3-simple id = "' + chartName + '" config="' + chartName + '"></c3-simple> </div>'
            var parent = angular.element(document.querySelectorAll('.chartsDiv')) // DOM element where the compiled template can be appended
            var linkFn = $compile(template);
            var content = linkFn(scope);
            parent.append(content);
        }

    }


}]);

私の質問に対してさらに明確にする必要がある場合はお知らせください。指示があれば、サンプルコードを添えてください。

4

1 に答える 1

1

それぞれが単一のコンポーネントを DOM に追加する 1 つ以上のディレクティブを作成することをお勧めします。したがって、1、2、および 3 は個別のディレクティブにする必要があります。私の経験では、複数のコンポーネントを追加するディレクティブを作成すると、扱いにくいコントローラーを扱いにくいディレクティブと交換することになる可能性があります。

config や columnDefs などについては、コントローラーで構成を定義するか、コントローラーを非常に軽量に保ちたい場合はコントローラーに渡される別のサービス/ファクトリーで構成を定義し、構成をディレクティブ スコープに渡します。これにより、アプリ内またはアプリ間でディレクティブを再利用できます。

コントローラーの変更を監視するには、ディレクティブscope.$watch()で適切な属性を指定してから、ディレクティブで適切な更新関数を呼び出します。これが4の意味だと思います。これは、私の例のドロップダウンで示されています。

$compileを使用せずに成功しましたが、他の人がそれを主張できるかもしれません。

注意: Angular が認識していない非同期機能を使用するサード パーティ ライブラリを使用している場合は、ディレクティブの更新動作をscope.$apply()内に配置する必要がある場合があります。そうしないと、DOM は動作しません。次の Angular ダイジェスト サイクルまで更新します。

HTML が 1 行または 2 行を超える場合は、templateUrlを使用することをお勧めします。

これは簡単な方法で jQuery を使用し たおもちゃの例です。

app.directive('chart', function() {
    return {
        restrict: 'EA',
        scope: {config: '='},
        templateUrl: 'chart.html',
        link: function(scope, element) {
            var el = element[0];

            function update() {
                $(el).html('<h4>' + scope.config.chartType + '</h4>');
            }

            scope.$watch('config', update, true);
        }
    }
});
于 2015-07-12T14:09:47.540 に答える