我需要在标签单击时在单个页面中显示多个 angularjs 指令。它可以是 c3 图表指令和 ng 网格指令的组合。我正在控制器中准备具有所有这些相关参数的模型,然后形成模板,然后在控制器本身中编译,这完全可以正常工作。当我意识到在控制器中进行 DOM 操作不是一个好习惯时,我正在尝试在自定义指令中进行操作。
该指令应支持以下功能:
- 模板应该是 C3 图表指令的组合。
- 该模板还可以具有 Angularjs ng Grid 指令以及 c3 图表指令。
- 将来我还想使用 Good Map 指令以及 C3 图表和 ng 网格指令。
- 并且其中一些指令应该支持自定义下拉菜单。
现在我已经在我的控制器中使用了以下代码,它运行良好。
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>';
}
所以在一个页面中我需要显示四个指令,它可以是 3 个 c3 图表和 1 个 ng 网格表指令,或者 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);
}
}
}]);
如果我需要进一步澄清我的问题,请告诉我。请提供一些示例代码的任何说明。