从控制器Angular JS重构特定于对象的逻辑

时间:2014-06-04 20:59:17

标签: javascript angularjs ng-grid

在我的控制器中,我目前拥有生成工作网格的所有功能。

控制器

app.controller('DocumentController',function($scope,DocumentService) {
  $scope.filterOptions = {
      filterText: '',
      useExternalFilter: false
  };
    $scope.totalServerItems =0;
    $scope.pagingOptions ={
        pageSizes: [5,10,100],
        pageSize: 5,
        currentPage: 1
    }
    //filter!
    $scope.dropdownOptions = [{
        name: 'Show all'

    },{
        name: 'Show active'
    },{
        name: 'Show trash'
    }];
    //default choice for filtering is 'show active'
    $scope.selectedFilterOption = $scope.dropdownOptions[1];


    //three stage bool filter
    $scope.customFilter = function(data){
        var tempData = [];
        angular.forEach(data,function(item){
            if($scope.selectedFilterOption.name === 'Show all'){
                tempData.push(item);
            }
            else if($scope.selectedFilterOption.name ==='Show active' && !item.markedForDelete){
                tempData.push(item);
            }
            else if($scope.selectedFilterOption.name ==='Show trash' && item.markedForDelete){
                tempData.push(item);
            }
        });
        return tempData;
    }



    //grabbing data
    $scope.getPagedDataAsync = function(pageSize, page,  searchText){
            var data;
            if(searchText){
                var ft = searchText.toLowerCase();
                DocumentService.get('filterableData.json').success(function(largeLoad){
                    //filter the data when searching
                    data = $scope.customFilter(largeLoad).filter(function(item){
                        return JSON.stringify(item).toLowerCase().indexOf(ft) != -1;
                    })
                    $scope.setPagingData($scope.customFilter(data),page,pageSize);
                })
            }
            else{
                DocumentService.get('filterableData.json').success(function(largeLoad){
                    var testLargeLoad = $scope.customFilter(largeLoad);
                    //filter the data on initial page load when no search text has been entered
                    $scope.setPagingData(testLargeLoad,page,pageSize);
                })
            }
    };
    //paging
    $scope.setPagingData = function(data, page, pageSize){
        var pagedData = data.slice((page -1) * pageSize, page * pageSize);
        //filter the data for paging
        $scope.myData = $scope.customFilter(pagedData);
        $scope.myData = pagedData;
        $scope.totalServerItems = data.length;
        if(!$scope.$$phase){
            $scope.$apply();
        }
    }

    //watch for filter option change, set the data property of gridOptions to the newly filtered data
    $scope.$watch('selectedFilterOption',function(){
            var data = $scope.customFilter($scope.myData);
            $scope.myData = data;
            $scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage);
            $scope.setPagingData($scope.myData,$scope.pagingOptions.currentPage,$scope.pagingOptions.pageSize);
    })
    $scope.$watch('pagingOptions',function(newVal, oldVal){
            $scope.getPagedDataAsync($scope.pagingOptions.pageSize,$scope.pagingOptions.currentPage,$scope.filterOptions.filterText);
            $scope.setPagingData($scope.myData,$scope.pagingOptions.currentPage,$scope.pagingOptions.pageSize);
    },true)


    $scope.message ="This is a message";
    $scope.gridOptions = {
      data: 'myData',
      enablePaging: true,
        showFooter:true,
        totalServerItems: 'totalServerItems',
        pagingOptions: $scope.pagingOptions,
        filterOptions: $scope.filterOptions,
        enableCellEdit: true,
        enableColumnReordering: true,
        enablePinning: true,
        showGroupPanel: true,
        groupsCollapsedByDefault: true,
        enableColumnResize: true
    }
    //get the data on page load
    $scope.getPagedDataAsync($scope.pagingOptions.pageSize, $scope.pagingOptions.currentPage);
});

这正常工作和页面,但这意味着在我想要使用网格的每个控制器上,我将不得不重新执行所有这些分页功能。所以我想把所有特定于网格的代码都放到它自己的类中。

var NgGrid = (function(){
    function NgGrid(gridOptions){
        this.service = gridOptions.service;
        this.filterOptions = gridOptions.filterOptions;
        this.pagingOptions  = gridOptions.pagingOptions;
        this.dropdownOptions = gridOptions.dropdownOptions;
        this.selectedFilterOption = this.dropdownOptions[1];
        this.totalServerItems = 0;
        this.myData = [];
        this.customFilter = function(data,propName){
            var tempData =[];
            angular.forEach(data,function(item){
                if(this.selectedFilterOption.name === 'Show all'){
                    tempData.push(item);
                }
                else if(this.selectedFilterOption.name === 'Show active' && !item[propName]){
                    tempData.push(item);
                }
                else if(this.selectedFilterOption.name === 'Show trash' && item[propName]){
                    tempData.push(item);
                }
            })
        }
        this.getPagedDataAsync = function(pageSize, page, searchText){
            var data;
            if(searchText){
                var ft = searchText.toLowerCase();
                //filter the data when searching
                this.service.get('filterableData.json').success(function(data){
                    data = this.customFilter(data).filter(function (item) {
                        return JSON.stringify(item).toLowerCase().indexOf(ft) != -1;
                    });
                    this.setPagingData(this.customFilter(data),page,pageSize);
                })
            }
            else{
                this.service.get('filterableDat.json').success(function(largeLoad){
                    var filtered = this.customFilter(largeLoad);
                    this.setPagingData(filtered,page, pageSize);
                })
            }
        }
        this.setPagingData = function(data, page, pageSize){
            var pagedData = data.slice((page-1) * pageSize, page * pageSize);
            this.myData = this.customFilter(pagedData);
            this.myData = pagedData;
            this.totalServerItems = data.length;
            if($scope.$$phase){
                $scope.apply();
            }
        }
    }
    return NgGrid;
});

我认为我添加到范围的大部分内容(如filterOptions和dropdownOptions)可能在NgGrid对象的构造函数中具有默认值,并且可能在控制器本身中被覆盖。我不确定的是

this.setPagingData = function(data, page, pageSize){
            var pagedData = data.slice((page-1) * pageSize, page * pageSize);
            this.myData = this.customFilter(pagedData);
            this.myData = pagedData;
            this.totalServerItems = data.length;
            //right here it gets fuzzy, not even totally sure why it works
            if($scope.$$phase){
                $scope.apply();
            }
        }
来自DocumentController.js文件的

我在其范围内放置了许多与网格相关的选项,所以当我创建我的NgGrid "class"时,我为此切换了$ scope。但有了这部分,我不知道该怎么做。我应该将控制器传递给NgGrid的构造函数吗?我可以通过这种方式访问​​控制器的$scope吗?或者,如果我只打算在控制器内部使用这个对象,我应该说它是螺旋式的,我知道会有一个$ scope和$$阶段可用并让我的课程保持原样吗?

1 个答案:

答案 0 :(得分:1)

绕过范围是不好的做法。虽然有一些有用的方法可以使用通用构造函数来创建可重用的基本控制器,服务等。我不认为这种情况需要在Angular组件之外工作。

我建议您将大部分逻辑和数据移动到一个或多个服务中。将这些服务注入控制器时,可以将它们返回的对象分配给范围变量,这将为您提供在控制器范围内拥有数据和方法的好处,同时不会使控制器本身膨胀。

为了帮助演示这可能如何工作,我创建了this demo,虽然它非常通用且不包含您的代码,但应该有助于提供一个模板来说明如何进行自己的重构。

相关问题