首页 > 解决方案 > 根据自定义 ui-grid 上的值启用和禁用单元格选择

问题描述

我在我们的应用程序中有一个自定义的 ui-grid,如下所示:

app.directive('stkGrid', ['$window', '$timeout', function($window, $timeout) {
    return {
        restrict: 'E',
        transclude: true,       
        scope: {
            data: '=',
            autoHeight: '=',
            selectionVariable: '=',
            onRowSelect: '&',
            onRowDeselect: '&',
            onRowsChanged: '&',
            selectAll: '@',
            canSelect: '@',
            columnDefs: '=',
            multiSelect: '@',
            noUnselect: '@'
        },
        controllerAs: 'parentCtrl',
        controller: ['$scope', '$element', function($scope, $element) {
            var $attrs = $element[0].attributes;

            $scope.$watch('selectionVariable', function(newValue, oldValue) {
                if (!newValue || !newValue.length) {
                    //$scope.gridApi.selection.clearSelectedRows();
                }
            });

            function rowSelectionChanged(row) {
                // row selection logic
            };

            $scope.stkGridOptions = {
                data: 'data',
                enableRowSelection: ($scope.canSelect != 'false'),
                enableSelectAll: ($scope.selectAll == 'true'),
                multiSelect: ($scope.multiSelect == 'true'),
                noUnselect: (typeof $scope.noUnselect !== 'undefined'),
                enableFullRowSelection: true,
                selectionRowHeaderWidth: 0,
                rowHeight:25,
                onRegisterApi: function(gridApi) {
                    //register api logic
                },
                columnDefs: (!!$scope.columnDefs ? $scope.columnDefs : [])
            };

            this.addColumn=function(col) {
                if (!!$scope.columnDefs) {
                    return;
                }

                $scope.stkGridOptions.columnDefs.push(col);
            };

            $scope.$watchCollection("columnDefs", function(newColumnDefs) {
                if (!newColumnDefs) {
                    return;
                }

                $scope.stkGridOptions.columnDefs = newColumnDefs;
            });
        }],
        link: function($scope, $element, $attrs) {
            // window resize logic
        },
        template: '<div ui-grid="stkGridOptions" ui-grid-selection></div><div ng-transclude></div>'
    };
}]).directive('stkCol', function() {
    return {
        require: '^^stkGrid',
        restrict: 'E',
        transclude: false,
        scope: {
            field: '@',
            displayName: '@',
            width: '@',
            maxWidth: '@',
            minWidth: '@',
            cellFilter: '@',
            cellClass: '@',
            cellTemplate: '=',
            type: '@',
            formatter: '&'
        },
        link: function(scope, element, attrs, stkGridCtrl) {
            stkGridCtrl.addColumn(scope);
        }
    };
});

此自定义 ui-grid 已在 home.html 中定义:

<stk-grid id="batchDocumentGrid" data="batchCtrl.documents" auto-height="180" selection-variable="batchCtrl.selectedDocument" ng-dblclick="homeCtrl.viewDocument(homeCtrl.selectedDocument)">
    <stk-col display-name="Include" field="include" cell-template="homeCtrl.documentFieldTemplates['include']" width="128"></stk-col>
    <stk-col display-name="Filename" field="fileName" cell-template="homeCtrl.documentFieldTemplates['fileName']"></stk-col>
    <stk-col display-name="Document Type" field="typeAbbreviation" cell-template="homeCtrl.documentFieldTemplates['typeAbbreviation']"></stk-col>
    <stk-col display-name="Amount" field="documentAmount" cell-template="homeCtrl.documentFieldTemplates['documentAmount']" width="120"></stk-col>
</stk-grid>

列定义在 home.js 中定义:

vm.documentFieldTemplates = {
        'include': '<input type="checkbox" ng-model="row.entity.include" />',
        'fileName': '<span ng-class="{inactive: !row.entity.include}">{{row.entity.fileName}}</span>',
        'typeAbbreviation': '<select class="form-control" ng-options="docType.DOCUMENT_TYPE_ABBREVIATION as docType.DOCUMENT_TYPE_ABBREVIATION for docType in grid.appScope.$parent.homeCtrl.docTypes" ng-model="row.entity.typeAbbreviation" ng-disabled="!row.entity.include" ng-change="grid.appScope.$parent.homeCtrl.docTypeChanged(row.entity.typeAbbreviation)"><option value="">&lt;Select Document Type&gt;</option></select>',
        'documentAmount': '<input type="text" ng-model="row.entity.documentAmount" ng-disabled="!row.entity.include || !grid.appScope.$parent.homeCtrl.isDocTypeSomething"/>'
    };

当文档类型更改时,以下方法将定义一个布尔值来启用或禁用金额列:

function docTypeChanged(typeAbbr) {
        if (typeAbbr == "SOMETHING") {
            vm.isDocTypeSomething = true;
        } else {
            vm.isDocTypeSomething = false;
        }
    }

但这里的问题是,由于这个变量是在网格级别范围内定义的,或者对于每一行都是通用的,所以当我更改文档类型时,它会针对所有行进行更改。如何对金额列进行此更改以启用和禁用特定行。

提前感谢您的帮助。

标签: angularjs

解决方案


不是为 typeAbbreviation 列添加更改侦听器,而是向数量列 ng-disabled 属性添加一个函数解决了这个问题。

vm.documentFieldTemplates = {
        'include': '<input type="checkbox" ng-model="row.entity.include" />',
        'fileName': '<span ng-class="{inactive: !row.entity.include}">{{row.entity.fileName}}</span>',
        'typeAbbreviation': '<select class="form-control" ng-options="docType.DOCUMENT_TYPE_ABBREVIATION as docType.DOCUMENT_TYPE_ABBREVIATION for docType in grid.appScope.$parent.homeCtrl.docTypes" ng-model="row.entity.typeAbbreviation" ng-disabled="!row.entity.include"><option value="">&lt;Select Document Type&gt;</option></select>',
        'documentAmount': '<input type="text" ng-model="row.entity.documentAmount" ng-disabled="!row.entity.include || grid.appScope.$parent.homeCtrl.isDisabled(row.entity.typeAbbreviation)" />'
    };

function isDisabled(typeAbbr) {
        if(typeAbbr == "SOMETHING") {
            return false;
        } else {
            return true;
        }
    }

推荐阅读