我是Angular 1.6和UI-grid的新手,所以我正在努力解决一些简单的问题。我希望在我的主控制器中定义一个UI网格,重新定义并重新使用来自不同Angular控制器的数据。更具体地说,我想在主Angular控制器中使用单个网格定义来拥有多个.CSHTML网格模板。我想从不同的Angular控制器填充网格数据数组,具有不同的数据和不同的列定义。一次只能有一个活动网格。
为每个控制器使用单独的网格定义,但我最终可能有20个网格;所以我不想在我的主Angular控制器中那么多可重复的膨胀。网格定义中唯一要更改的部分是列定义和数据。下面是一个简化的项目布局,以帮助讨论。
在我的主要Angular控制器中,我有一个UI网格定义,我想从不同文件中的多个Angular控制器重用它。网格定义如下:
//MainController in app.js
(function () {
'use strict';
angular.module('CRNApp', ['ui.bootstrap', 'ui.grid', 'ui.grid.autoResize', 'ui.grid.emptyBaseLayer', 'ui.grid.selection']);
MainController.$inject = ['$scope', '$http', '$uibModal', '$log','uiGridConstants'];
angular.module('CRNApp')
.controller('MainController', MainController);
$scope.policyList = { //grid options and data for policy data
rowHeight: 40,
enableFiltering: true,
enableRowSelection: true,
enableRowHeaderSelection: false,
data: 'policyData',
columnDefs: [ //the column defs will be different for each different controller
{ name: 'PolicyId'},
{ name: 'PolicyState'},
{ name: 'AgentName' },
{ name: 'InforcePremium' },
{ name: 'LOB'}
]
};
$scope.policyData = []; //stores policy array returned from MVC controller to UI
$scope.policySelected = 'false'; //tracks if a row is selected. Allows row-depenendent nav buttons to be enabled on bav bar
$scope.mySelectedPolicy = {};
//grid options for processor grid
$scope.policyList.multiSelect = false;
$scope.policyList.modifierKeysToMultiSelect = false;
$scope.policyList.noUnselect = false;
$scope.policyList.onRegisterApi = function (policyApi) {
$scope.policyApi = policyApi;
$scope.policyApi.selection.on.rowSelectionChanged($scope, function (row) {
if (row.isSelected) {
$scope.policySelected = 'true';
$scope.mySelectedPolicy = row.entity; //copy selected row so that we can access it from processor controller
}
else
$scope.policySelected = 'false';
});
};
//this function recalculates the height of the visible grid after the row count changes
$scope.getPolicyTableHeight = function () {
var rowHeight = 30; // your row height
var headerHeight = 30; // your header height
return {
height: ($scope.policyList.data.length * rowHeight + headerHeight) + "px"
};
};
}());
在主_Layout.cshtml中,导航栏上有一个按钮,该按钮绑定到名为“PolicyController”的单独Angular控制器中的函数。该函数的名称称为“loadPoliciesGrid()”。此函数使用数据填充policyList网格定义中的policyData数组(请参阅上面的主控制器)。我将在页面上有多个按钮,在不同的控制器中调用类似的功能。例如,我将有一个Processor按钮,在ProcessorController Angular文件中调用“LoadProcessors()”函数。 “LoadProcessors()”函数将在主控制器中重复使用相同的网格定义,但列defs和网格数组将不同。
<input style="margin-top: 8px !important; margin-bottom: 8px !important; margin-left: 8px !important;" type="submit" value="Get Records" ng-controller="PolicyController" ng-click="loadPoliciesGrid()" class="btn btn-default btn-sm">
“PolicyController”中用于加载网格数据的功能如下所示。将有其他Angular控制器调用自己的数据,主控制器中的网格定义应该以某种方式具有相应的列defs:
//PolicyController in policy.js
(function () {
angular.module('CRNApp');
PolicyController.$inject = ['$scope', '$http', '$uibModal', '$log'];
angular.module('CRNApp')
.controller('PolicyController', PolicyController);
function PolicyController($scope, $http, $uibModal, $log) {
$scope.loadPoliciesGrid = function () {
$scope.$parent.loading = true;
$http.get("/api/Policy")
.then(function (responsePol) {
$scope.$parent.policyData = responsePol.data;
$scope.$parent.showGrid = 'policies';
$scope.$parent.loading = false;
})
.catch(function (error) {
console.log(error);
});
};
};
}());
网格模板绑定到Index.cshtml页面中的策略控制器,该页面将作为子页面加载到主_Layout.cshtml页面中。这些模板中的每一个都应该将它们的数据绑定到同一个UI网格。:
@*Index.cshtml. Each template is bound to a different Angular controller*@
@{ViewBag.Title = "ICS Portal - Home Page";}
<div ng-include="'templates/policiesGrid.cshtml'" ng-controller="PolicyController"></div>
<div ng-include="'templates/processorGrid.cshtml'" ng-controller="ProcessorController"></div>
<div ng-include="'templates/usersGrid.cshtml'" ng-controller="UserController"></div>
网格标记容器在一个名为policiesgrid.cshtml的单独模板文件中定义。每个网格标记模板都在一个单独的文件中,但是shoudl引用相同的UI网格定义:
<div style="margin-left: auto; margin-right: auto;">
<div ui-if="policyList.data.length>0" ng-style="getPolicyTableHeight()"
ui-grid-auto-resize ui-grid-empty-base-layer ui-grid-selection id="policyGrid"
ui-grid="policyList" class="processorGrid" ng-show="showGrid == 'policies'"
style="margin-left: auto; margin-right: auto;">
</div>
</div>
答案 0 :(得分:1)
您应该使用服务来获取数据,但无论如何,有很多方法可以实现您想要的(如AngularJS中的所有内容)。如果您不想重构代码,并且我理解正确,您希望控制器之间进行基本通信。
最简单的方法是使用网格在控制器上设置观察器。
因此,在设置网格的控制器上执行以下操作:
$scope.$on('dataGridChangedMessage', (event, argumentsPassedToGrid) => {
$scope.policyList.columnDefs = argumentsPassedToGrid.columnDefs;
$scope.policyList.data = argumentsPassedToGrid.data;
// you might neeed here to refresh the grid using API, something like: policyApi.grid.refresh();
// or try to trigger digest cycle manually if it doesn't work with: $timeout($scope.$apply());
});
在你的其他控制器上,你需要注入$ rootScope并广播你的数据/ columnDefs - 当你的$ http承诺得到解决时:
$rootScope.$broadcast('dataGridChangedMessage', {
columnDefs: [], // this is your new column defs
data: [] // this is your new data
};
所以你可以让ui网格控制器显示数据和控制器发送类似的数据:
controller1 =&gt;控制器UI GRID&lt; = controller2
即使上面会有效,但更好的方法是:
创建全新的服务,
在控制器UI GRID中注入服务,
删除那些控制器(在我的示例中为controller1和controller2)
从服务中返回$ http承诺 - 甚至更好地设置$resource并将其用于不同的终端。
从服务中获取不同的数据(在UI GRID控制器中)并且一旦承诺 解决了你只需刷新网格数据(类似于上面的例子)
所以只使用一个控制器和一个服务 - 没有必要进行$ broadcasts
如果您担心重复,可以设置显示网格数据的通用组件,在服务和通用功能上设置$ resource - 这将需要您可以在模板中设置的两个或任意数量的参数。如果你正在使用组件(你应该)/指令:
,就像这样<my-ui-grid-generic-component url-key="some-name-1" url-params="{something: whatever}"></my-ui-grid-generic-component>
并且在服务中你会用键定义对象 - 像这样的端点:
let uigridDataAPIs = {
'some-name-1': 'http://google.com',
'some-name-2': 'http://google.com',
};
一旦在主控制器中注入该服务,您只需要一个通用组件/指令控制器上的函数来调用service $ resource - 如下所示:
MyInjectedService.getResource($scope.urlKey, $scope.urlParams).then(resolve => {
// logic to update grid - similar to first example
});
您需要设置泛型$ http函数或$ resource,以返回该服务的promise。别忘了在组件/指令上设置urlKey和urlParams绑定。
此外,如果您想学习更高级的做事方式,请查看:
我强烈推荐这一个:https://github.com/toddmotto/angularjs-styleguide
https://github.com/angular-redux/ng-redux
https://rxjs-dev.firebaseapp.com/
请记住以上所有内容只是为了指明未来的正确方向,我还没有对我写过的任何东西进行过测试 - 大多数都是假设的,并且我已经将它设置在带有ui-grid&#的项目上39; s,所以你需要填补空白,一旦你进入下一步并陷入困境 - 发一个新问题,有人会帮助你。