Angularjs控制器用于多个视图

时间:2015-11-01 17:47:25

标签: angularjs angular-ui-grid

如果我需要重用以下控制器(放在App.js中),我需要删除特定于视图的columnDefs并将它们分开放置(View,html文件)。

这里我在控制器本身设置了ui-grid的gridOptions。即使我设法将其放在UI(脚本标记)中, uiGridConstants 在视图中也不可用。那么我该如何解决这个问题,以便我可以将该文件重用于多个视图。 我现在已经把头发拉了一段时间了,我是一个有角度的新手,所以请帮忙。

(function () {
    gridFactory = function ($http) {
        return {
            callWebApi: function () {
                return $http({
                    method: 'GET',
                    url: '/api/PatientCategoryApi/PatCat',
                    params: this.callParams.paginationOptions,
                    headers: { 'Content-Type': 'application/Json' }
                })
            },
            callParams: {}
        }
    };
    patientCategoryController = function ($scope, $attrs, uiGridConstants, gridFactory) {

        $scope.gridOptions = {

            paginationPageSizes: [5, 10, 20, 25, 50],
            paginationPageSize: 10,
            useExternalPagination: true,
            useExternalSorting: true,
            enableSorting: true,
            rowHeight: 30,
            columnDefs: [
                { field: 'Id', sortDirectionCycle:[uiGridConstants.ASC, uiGridConstants.DESC] },
                { field: 'Code' },
                { field: 'Name' },
                { field: 'Description' },
                { field: 'ModifiedTime', cellFilter: 'date:"dd-MMM-yy h:mm:ss a"' },
                { field: 'History', enableSorting: false }
            ],
            onRegisterApi: function (gridApi) {
                $scope.gridApi = gridApi;
            }
        };

        var callData = {};

        var paginationOptions = {};
        paginationOptions.Page = 1;
        paginationOptions.Take = 10;
        paginationOptions.SortOrder = 'Asc';
        paginationOptions.PropName = 'Id';
        callData.paginationOptions = paginationOptions;
        gridFactory.callParams = callData;
        var promise = gridFactory.callWebApi();
        promise.then(
            function successCallback(response) {
                $scope.gridOptions.totalItems = response.data.TotalCount;
                $scope.gridOptions.data = response.data.Collection;
                $scope.gridHeight = gridFactory.getGridHeight($scope.gridOptions);
            }, function errorCallback(response) {
                alert('Some problem while fetching data!!');
            });
    }
    patientCategoryController.$inject = ['$scope', '$attrs', 'uiGridConstants', 'gridFactory'];
    gridFactory.$inject = ['$http'];
    angular.module('abvhHisApp', ['ui.grid', 'ui.grid.autoResize', 'ui.grid.pagination', 'ui.grid.resizeColumns']);
    angular.module('abvhHisApp').controller('patientCategoryController', patientCategoryController);
    angular.module('abvhHisApp').factory('gridFactory', gridFactory);
}());

2 个答案:

答案 0 :(得分:1)

我有完全相同的问题,有许多网格视图,并希望编写DRY代码。 我的解决方案是为网格控制器创建一个基类,并为不同的视图继承它。

  

基类(为网格提供无限滚动):



function InfiniteGrid() {
        var vm = this;

        vm.firstPage = vm.lastPage = 1;
        vm.keepPages = 3;
        vm.pageSize = 100;
        vm.totalCount = 0;

        vm.init();

        vm.data = vm.loadData();

        vm.uiGridOptions = {
            enableSorting: true
            ,columnDefs: vm.columnDefs
            ,data: 'vm.data'
            ,infiniteScrollRowsFromEnd: 1
            ,infiniteScrollUp: true
            ,infiniteScrollDown: true
            ,onRegisterApi: function(gridApi){
                gridApi.infiniteScroll.on.needLoadMoreData(vm.$scope, vm.getDataDown);
                gridApi.infiniteScroll.on.needLoadMoreDataTop(vm.$scope, vm.getDataUp);
                vm.gridApi = gridApi;
            }
        };

        vm.$scope.$watch('vm.filterText', function(search){
            vm.firstPage = vm.lastPage = 1;
            vm.data = vm.loadData(1, search);
        });

    }

    InfiniteGrid.prototype = {
        loadData : function (page, search) {
            var vm = this;
            return vm.Entity.query({page: page, limit: vm.pageSize, search: search}, function (data, headers) {
                vm.totalCount = data.total_count = 1 * headers('X-List-Total');
                vm.$timeout(function () {
                    vm.gridApi.infiniteScroll.dataLoaded(vm.firstPage > 1, vm.lastPage < Math.floor(vm.totalCount / vm.pageSize) + 1);
                });
            });
        },
        getDataDown : function () {
            var gridApi = this,
                vm = gridApi.grid.appScope.vm;
            vm.loadData(vm.lastPage + 1).$promise.then(function (newData) {
                vm.lastPage++;
                gridApi.infiniteScroll.saveScrollPercentage();
                vm.data = vm.data.concat(newData);
                gridApi.infiniteScroll.dataLoaded(vm.firstPage > 1, vm.lastPage < Math.floor(newData.total_count / vm.pageSize) + 1)
                    .then(vm.checkDataLength.bind(vm, 'up'));
            });
        },

        getDataUp : function () {
            var gridApi = this,
                vm = gridApi.grid.appScope.vm;
            vm.loadData(vm.firstPage - 1).$promise.then(function (newData) {
                vm.totalCount = newData.total_count;
                vm.firstPage--;
                gridApi.infiniteScroll.saveScrollPercentage();
                vm.data = newData.concat(vm.data);
                gridApi.infiniteScroll.dataLoaded(vm.firstPage > 1, vm.lastPage < Math.floor(newData.total_count / vm.pageSize) + 1)
                    .then(vm.checkDataLength.bind(vm, 'down'));
            });
        },

        checkDataLength : function (direction) {
            var vm = this;
            if (vm.lastPage - vm.firstPage > vm.keepPages) {
                if (direction === 'up') {
                    vm.data = vm.data.slice(vm.pageSize);
                    vm.firstPage++;
                    vm.$timeout(function () {
                        vm.gridApi.infiniteScroll.dataRemovedTop(vm.firstPage > 1, vm.lastPage < Math.floor(vm.totalCount / vm.pageSize) + 1);
                    });
                } else {
                    vm.data = vm.data.slice(0, vm.pageSize * vm.keepPages);
                    vm.lastPage--;
                    vm.$timeout(function () {
                        vm.gridApi.infiniteScroll.dataRemovedBottom(vm.firstPage > 1, vm.lastPage < Math.floor(vm.totalCount / vm.pageSize) + 1);
                    });
                }
            }
        },

        deleteRow : function (rowId) {
            var vm = this,
                row = vm.$filter('filter')(vm.data, {_id: rowId})[0],
                rowIdx = vm.data.indexOf(row);

            vm.Entity.delete({id: rowId}).$promise.then(function () {
                vm.data.splice(rowIdx, 1);
                vm.toastr.success("Record successfully deleted!", "Success", {extendedTimeOut: 1500, timeOut: 1500});
            }, function (data, status) {
                if (status !== 401) {
                    vm.toastr.error(data.data.message);
                }
            });
        }
    };

    return InfiniteGrid;
});
&#13;
&#13;
&#13;

  

继承的控制器代码

&#13;
&#13;
angular.module('myApp')
        .controller('SomeGridCtrl', ['$scope', '$timeout', '$resource', 'toastr', '$filter', '$routeParams', SomeGridCtrl]);

    function SomeGridCtrl($scope, $timeout, $resource, toastr, $filter, $routeParams)
    {
        var vm = this;
        $scope.vm = vm;
        vm.$scope = $scope;
        vm.toastr = toastr;
        vm.$filter = $filter;
        vm.$timeout = $timeout;
        vm.$resource = $resource;
        vm.$routeParams = $routeParams;

        // Call the parent constructor
        infiniteGrid.call(vm);
    }

    // Inherit the prototype
    SomeGridCtrl.prototype = Object.create(infiniteGrid.prototype);

    SomeGridCtrl.prototype.init = function() {
        var vm = this;

        vm.Entity = vm.$resource('/api/item/:id');
        vm.columnDefs = [
            {
                displayName: "Title"
                ,field: "title"
                //,filter: 'text',
                ,cellTemplate: '<div class="ui-grid-cell-contents"><a ng-href="#/card/{{ row.entity._id }}" ng-bind="COL_FIELD"></a></div>'
            },{
                displayName: "URL"
                ,field: "url"
                ,filter: 'text'
                ,cellTemplate: '<div class="ui-grid-cell-contents"><a ng-href="#/card/{{ row.entity._id }}" ng-bind="COL_FIELD"></a></div>'
            },{
                displayName: "Partner"
                ,field: "partner.fullName"
                //,filter: 'text'
            },{
                field: 'review_count'
                ,displayName: 'Reviews'
                ,width: 80
                ,cellTemplate: '<div class="ui-grid-cell-contents"><a ng-href="#/card/{{ row.entity._id }}/reviews" ng-bind="COL_FIELD"></a></div>'
            },{
                displayName: "Created on"
                ,field: 'created'
                ,cellFilter: 'amCalendar'
                ,filter: false
            },{
                displayName: "Delete"
                ,field: "dummy"
                //,width: 80
                ,cellTemplate: '<div class="ui-grid-cell-contents"><a ng-click="grid.appScope.vm.deleteRow(row.entity._id)" confirm="Are you sure?" class="btn btn-xs btn-danger">Delete</a></div>'
            }
        ];
    };
&#13;
&#13;
&#13;

答案 1 :(得分:0)

好的,这就是我解决这个问题的方法。

我想要实现的目标?我在其中一个页面中使用了AngularJs的ui-grid。但我意识到我有很多这样的页面,网格显示了许多不同的表格数据。那么如何确保DRY代码就成了问题。 @Constantine建议使用原型模式继承。所以现在要适应我开始搜索更多AngularJs控制器继承并遇到http://jasonwatmore.com/post/2014/03/25/AngularJS-A-better-way-to-implement-a-base-controller.aspx 我试过这种方法。这是如何。

App.js如下。

(function () {
    gridFactory = function ($http) {
        var service = {
            callWebApi: callWebApiFunction,
            callParams: {}
        };

        return service;

        function callWebApiFunction() {
            return $http({
                method: 'GET',
                url: this.callParams.uri,
                params: this.callParams.paginationOptions,
                headers: { 'Content-Type': 'application/Json' }
            })
        };
    }

    function baseGridController($scope, gridFactory) {
        $scope.diaryEntry = { name: 'default diary entry from baseGridController' };
        $scope.saveDiaryEntry = function () {
            gridFactory.SaveDiaryEntry($scope.diaryEntry);
        };

        // The following grid options are common fro all grids.
        // So the following code is shared.
        $scope.gridOptions.rowHeight = 30;
        $scope.gridOptions.useExternalPagination = true;
        $scope.gridOptions.useExternalSorting = true;
        $scope.gridOptions.enableSorting = true;
        $scope.gridOptions.onRegisterApi = function (gridApi) {
            $scope.gridApi = gridApi;
        }


        gridFactory.callParams = $scope.callData;
        var promise = gridFactory.callWebApi();
        promise.then(
            function successCallback(response) {
                $scope.gridOptions.totalItems = response.data.TotalCount;
                $scope.gridOptions.data = response.data.Collection;
            }, function errorCallback(response) {
                alert('Some problem while fetching data!!');
            });

    }

    angular.module('abvhHisApp', ['ui.grid', 'ui.grid.autoResize', 'ui.grid.pagination', 'ui.grid.resizeColumns']);
    angular.module('abvhHisApp').controller('baseGridController', baseGridController);
    baseGridController.$inject = ['$scope', 'gridFactory'];
    angular.module('abvhHisApp').factory('gridFactory', gridFactory);
    gridFactory.$inject = ['$http'];
}());

在html文件中,在 head 标记内,我有一个脚本标记,如下所示。

<script type="text/javascript">
    (function () {
        'use strict';
        function patientCategoryController($scope, $controller, uiGridConstants) {
            $scope.gridOptions = {

                paginationPageSizes: [5, 10, 20, 25, 50],
                paginationPageSize: 10,
                // You can override the height and other properties here.
                //rowHeight: 60,
                columnDefs: [
                    { field: 'Id', sortDirectionCycle: [uiGridConstants.ASC, uiGridConstants.DESC] },
                    { field: 'Code' },
                    { field: 'Name' },
                    { field: 'Description' },
                    { field: 'ModifiedTime', cellFilter: 'date:"dd-MMM-yy h:mm:ss a"' },
                    { field: 'History', enableSorting: false }
                ]
            };

            var defaultCallData = {};
            var paginationOptions = {};
            paginationOptions.Page = 1;
            paginationOptions.Take = 10;
            paginationOptions.SortOrder = 'Asc';
            paginationOptions.PropName = 'Id';
            defaultCallData.paginationOptions = paginationOptions;
            defaultCallData.uri = '/api/PatientCategoryApi/PatCat';
            $scope.callData = defaultCallData;

            $controller('baseGridController', { $scope: $scope });
        }

        angular.module('abvhHisApp').controller('patientCategoryController', patientCategoryController);
        patientCategoryController.$inject = ['$scope', '$controller', 'uiGridConstants'];
    }());
</script>

请注意以下事项。

  1. 在上述脚本标记之前,在 head 标记内,应引用以下脚本。

  2. 上面列出了App.js内容。 ui-grid.js是ui网格代码http://ui-grid.info/

  3. 因此,您可以在html页面脚本标记中进行特定设置。然后可以共享的公共代码将在App.js文件中。

    到目前为止,我觉得这是一种优雅的方法。