如何将键和值推送到角度控制器

时间:2016-12-14 07:48:20

标签: angularjs arrays

我想根据用户提供的行数和列数来过滤数据。

我从给定位置读取excel文件后获取控制器上的数据,并且excel可能包含多个工作表。工作表名称将显示在下拉列表中。

我想根据通过列的标题名称过滤行数据,以便该行只有值,直到定义列。目前我正在获得整行值。

我写过这样的逻辑,但这不起作用。

var rowData=[];
for(var i=0;i<headerNames.length;i++){//headerNames contains column names
   for(var j=0;j<data.length;j++){//data contains the rows data
      for(var keyName in data[j])
        if(angular.equals(keyName,headerNames[i])){
           rowData.push({'keyName':data[j][keyName]})//I want only the key,values which matches the column names. I want to set the keyName value as array key but I am not getting its value instead it is coming like keyName:18
        }
      }
   }
}

为代码添加plunker。 http://plnkr.co/edit/28Z44xDBug7nFCQnKZJL?p=preview

我能够在UI上过滤数据,并根据用户输入仅获取行和列数据。 但我需要控制器上的相同数据,以便我可以将其保存在MongoDb中。我想根据列输入过滤行数据。所以,我只得到行数据,直到列定义。

请建议我如何过滤数据并且可以拼接行值,以便在行i中可以具有最多定义的列数的值。例如,如果用户输入了4行和5列,那么在我的行Data中,我只能拥有最多5列的值以及我可以从数组中删除的所有其他值。在我的代码中,我目前无法将键值设置为数组键。

请帮我解决此问题。

1 个答案:

答案 0 :(得分:0)

您应该尝试在内循环中更改为:

var obj = {};
obj[keyName] = data[j][keyName];
rowData.push(obj);

注意:我还对工作表选择进行了一些改进,现在它在您上传新文件时默认为第一张工作表。 我也认为你的重置有问题,它在重置后不接受新的工作簿,它只使用前一个。

// Code goes here
angular.module('app', ['ui.grid'])
    .controller('MainCtrl', ['$scope', function ($scope) {
        var vm = this;
        vm.gridOptions = {};
        vm.reset = reset;
        vm.selectedSheet = '';
        vm.sheetIndex = 0;
        function reset() {
            vm.gridOptions.data = [];
            vm.gridOptions.columnDefs = [];
            vm.selectedSheet = '';
            vm.sheetIndex = 0;
            vm.sheetNames = [];
            vm.updatedData = null;
        }

        vm.readSheet = function () {
            var workbook = XLSX.read(vm.data, {
                type: 'binary'
            });
            var headerNames = XLSX.utils.sheet_to_json(workbook.Sheets[workbook.SheetNames[vm.sheetIndex]], {
                header: 1
            })[0];
            vm.sheetNames = workbook.SheetNames; //Passed the sheet names to scope variable
            if(!vm.selectedSheet && vm.sheetNames && vm.sheetNames.length > 0) {
                vm.selectedSheet = vm.sheetNames[0];
            }
            var data = XLSX.utils.sheet_to_json(workbook.Sheets[workbook.SheetNames[vm.sheetIndex]]);
            var row = $scope.rowCount;
            var col = $scope.columnCount;
            if (col != undefined && col != '') {
                headerNames.splice($scope.columnCount);
            }
            vm.gridOptions.columnDefs = [];
            headerNames.forEach(function (h) {
                vm.gridOptions.columnDefs.push({
                    field: h
                });
            });
            if (row != undefined && row != '') {
                data.splice($scope.rowCount);
            }
            vm.gridOptions.data = data;
            var rowData = [];
            for (var i = 0; i < headerNames.length; i++) {
                for (var j = 0; j < data.length; j++) {
                    for (var keyName in data[j]) {
                        if (angular.equals(keyName, headerNames[i])) {
                            var obj = {};
                            obj[keyName] = data[j][keyName];
                            rowData.push(obj);//Here I am trying to create 
                            //an similar data kind array which will have only the row values upto
                            //the column defined. But in keyName I am not getting the key value
                            //Also please suggest is this the right approach. I need only the data
                            //here upto the row and column defined by user so that I can save that data
                            //to mongoDB
                        }
                    }
                }
            }
            vm.updatedData = rowData;
        };
        vm.onLoadData = function (data) {
            vm.data = vm.data || data;
            vm.readSheet();
        };
        vm.sheetChange = function () {
            vm.sheetIndex = vm.sheetNames.indexOf(vm.selectedSheet);
            vm.readSheet();
        };
        $scope.$watch('columnCount', function(newVal, oldVal) {
            if(newVal !== oldVal) {
                vm.readSheet();
            }
        });
        $scope.$watch('rowCount', function(newVal, oldVal) {
            if(newVal !== oldVal) {
                vm.readSheet();
            }
        });
    }])
    .directive("fileread", [function () {
        return {
            scope: {
                onLoadData: '&'
            },
            link: function ($scope, $elm, $attrs) {
                $elm.on('change', function (changeEvent) {
                    var reader = new FileReader();
                    reader.onload = function (evt) {
                        $scope.$apply(function () {
                            $scope.onLoadData({
                                data: evt.target.result
                            });
                            $elm.val(null);
                        });
                    };
                    reader.readAsBinaryString(changeEvent.target.files[0]);
                });
            }
        }
    }]);
/* Styles go here */

body {
  /* font-family: Verdana; */
  padding: 20px;
}

.grid {
  width: 100%;
  height: 250px;
}

.grid-msg-overlay {
  position: absolute;
  top: 0;
  bottom: 0;
  width: 100%;
  background: rgba(0, 0, 0, 0.4);
}

.grid-msg-overlay .msg {
  opacity: 1;
  position: absolute;
  top: 20%;
  left: 20%;
  width: 60%;
  height: 50%;
  background-color: #eee;
  border-radius: 4px;
  border: 1px solid #555;
  text-align: center;
  font-size: 24px;
  display: table;
}

.grid-msg-overlay .msg > .center {
  display: table-cell;
  vertical-align: middle;
}

.grid input[type="file"] {
  font-size: 14px;
  display: inline-block;
}
<!DOCTYPE html>
<html ng-app="app">

  <head>
    <link data-require="bootstrap-css@*" data-semver="3.3.1" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.1/css/bootstrap.min.css" />
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.16/angular.js"></script>
    <script src="https://cdn.rawgit.com/SheetJS/js-xlsx/v0.8.0/dist/xlsx.full.min.js"></script>
    <script src="https://cdn.rawgit.com/SheetJS/js-xlsx/v0.8.0/dist/ods.js"></script>
    <script src="http://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/release/3.0.0-rc.22/ui-grid.min.js"></script>
    <link rel="stylesheet" href="http://cdn.rawgit.com/angular-ui/ui-grid.info/gh-pages/release/3.0.0-rc.22/ui-grid.min.css" />
    <link rel="stylesheet" href="main.css" type="text/css" />
  </head>

  <body>
   <div ng-controller="MainCtrl as vm">
      <button type="button" class="btn btn-success" ng-click="vm.reset()">Reset Grid</button>
      <br />
      <br />
      <div id="grid1" ui-grid="vm.gridOptions" class="grid">
        <div class="grid-msg-overlay" ng-show="!vm.gridOptions.data.length">
          <div class="msg">
            <div class="center">
              <span class="muted">Select Spreadsheet File</span>
              <br />
               <input type="file" accept=".xls,.xlsx,.ods"  multiple="true"  fileread="" on-load-data="vm.onLoadData(data)"/>
            </div>
          </div>
        </div>
      </div>
      <div ng-show="vm.sheetNames && vm.sheetNames.length > 0">
        <br/>
        <div ng-show="vm.sheetNames.length > 1">
          <select ng-model="vm.selectedSheet" ng-options="names as names for names in vm.sheetNames" 
          ng-change="vm.sheetChange()"></select>
        </div>
        <br/>
        <label>Column:
          <input type="text" name="col" ng-model="columnCount">
        </label>
        <br/>
        <label>Row:
          <input type="text" name="row" ng-model="rowCount">
        </label>
        <br/><br/>
        <div ng-show="vm.updatedData">
          <label>Updated result:</label>
          <div>{{vm.updatedData}}</div>
        </div>
      </div>
    </div>
    <script src="app.js"></script>
  </body>

</html>

Plunker update