简体   繁体   English

无法将动态数据加载到ui-grid下拉列表中

[英]Unable to load dynamic data into ui-grid dropdown

I am using ui-grid with AngularJS (and MySQL at backend) for a project. 我正在使用带有AngularJS的 ui-grid (以及后端的MySQL)作为项目。 I got a table which gets its data from MySQL database. 我有一个从MySQL数据库获取数据的表。 Its rows (or cells) are editable (as mentioned in this example on ui-grid website). 它的行(或单元格)是可编辑的(如ui-grid网站上的此示例中所述)。 One column of the table has dropdown. 该表的一列有下拉列表。 Dropdown is working perfectly with hard coded data as described in that example. Dropdown与硬编码数据完美配合,如该示例中所述。 I want to populate it from database but it shows empty dropdown list everytime I tried. 我想从数据库填充它,但每次我尝试时它都显示空的下拉列表。

Fetching of data from database is done by service which is injected into the controller with intention to run the code that gets data from database (ie $http.get('/some/route')) so that we have all the data for table rows and dropdown list in hand before or at the time of page loading. 从数据库中获取数据是通过服务完成的,该服务被注入到控制器中,意图运行从数据库获取数据的代码(即$ http.get('/ some / route')),以便我们拥有表的所有数据在页面加载之前或加载时手中的行和下拉列表。

But the variable (sitesD) that gets data for dropdown when printed, shows it is undefined. 但是,在打印时获取下拉数据的变量(sitesD)显示它未定义。

Here is the controller: 这是控制器:

angular.module('WorkersCtrl', []).controller('WorkersController', function($scope, $http, serverData) {

$scope.gridOptions = {enableHorizontalScrollbar: 1};

/* getting rows from databse by using "serverData" custom service */
serverData.getData().then(function(response) {
        $scope.gridOptions.data = response.data[0];
        $scope.sitesData = response.data[1];
});
var sitesD = $scope.sitesData;
$scope.gridOptions.columnDefs = [
    { field: 'first_name', width:150, enableCellEdit: true},
    { field: 'last_name', width:150},
    { field: 'father_first_name', width:150},
    { field: 'father_last_name', width:150},
    { field: 'mother_first_name', width:150},
    { field: 'mother_last_name', width:150},
    { field: 'sex', width:50, editableCellTemplate: 'ui-grid/dropdownEditor',
        editDropdownValueLabel: 'gender', editDropdownOptionsArray: [
          { id: 'M', gender: 'Male' },
          { id: 'F', gender: 'Female' }]},
    { field: 'address', width:250},
    { field: 'phone', width:100, type: 'number'},
    { field: 'date_of_birth', width:150, type: 'date', cellFilter: 'date:"yyyy-MM-dd"'},
    { field: 'post_code', displayName: 'Post', width:50},
    { field: 'joining_date', width:150, type: 'date', cellFilter: 'date:"yyyy-MM-dd"'},
    { field: 'rate', width:50, type: 'number'},
    { field: 'site_name', width:150, editableCellTemplate: 'ui-grid/dropdownEditor',
    editDropdownIdLabel:'site_id', editDropdownValueLabel: 'site_name', editDropdownOptionsArray: sitesD },
];
alert(sitesD); //checking the variable value: it shows undefined.

$scope.gridOptions.onRegisterApi = function(gridApi){
    $scope.gridApi = gridApi;
};

$scope.addData = function() {
    $scope.gridOptions.data.push({
        'first_name': '',
        'last_name': '',
        'father_first_name': '',
        'father_last_name': '',
        'mother_first_name': '',
        'mother_last_name': '',
        'sex': '',
        'address': '',
        'phone': '',
        'date_of_birth': '',
        'post_code': '',
        'joining_date': '',
        'rate': '',
        'site_name': ''
    });
};
});

Code of service is following: 服务代码如下:

angular.module('GeekService', []).factory('serverData', ['$http', function($http) {
    return {
        getData: function() {
            return $http.get('/workers')
        }
    }
}]);

Here is the screenshot of page when alert(sitesD); 这是alert(sitesD);的页面截图alert(sitesD); runs: 运行: 在此输入图像描述

What I understand is variable gets value after the page loads and so the editDropdownOptionsArray gets no value for dropdown. 我理解的是变量在页面加载后获取值,因此editDropdownOptionsArray没有获取下拉列表的值。

All these are assumptions I made while looking for solution but haven't sceeded yet. 所有这些都是我在寻找解决方案时所做的假设,但还没有进行过。 Please help me. 请帮我。 I feel I am even didn't understand where's the problem. 我觉得我甚至不明白问题出在哪里。

Feel free to ask further information if needed. 如果需要,请随时询问更多信息。

PS: While writing the question I found there is version incompatibility between my Angular and ui-grid. PS:在写这个问题时,我发现我的Angular和ui-grid之间存在版本不兼容。 ui-grid 3.x is compatible with Angular's 1.4.x but I'm using ui-grid 3.x with Angular 1.5.5. ui-grid 3.x与Angular的1.4.x兼容,但我使用的是带有Angular 1.5.5的ui-grid 3.x. Is it can be the reason? 这可能是原因吗?

EDIT: Here is the screenshot, showing how the dropdown looks: 编辑:这是截图,显示下拉列表的外观: 在此输入图像描述

Harmanpreet, Harmanpreet,

Since you are bringing in dynamic content asynchronously I would recommend looking at the ui-grid "editDropdownRowEntityOptionsArrayPath" functionality instead of "editDropdownOptionsArray" as that functionality appears to be meant for static values as you are discovering now. 由于您是异步引入动态内容,我建议您查看ui-grid“editDropdownRowEntityOptionsArrayPath”功能而不是“editDropdownOptionsArray”,因为该功能似乎是针对您现在发现的静态值。 There is information on this on the UI-grid API site: http://ui-grid.info/docs/#/api/ui.grid.edit.api:ColumnDef UI-grid API网站上有相关信息: http//ui-grid.info/docs/#/api/ui.grid.edit.api : ColumnDef

If the data is a static list and won't be changing or dependent then maybe the code below would work as well, thanks for reaching out: 如果数据是静态列表并且不会改变或依赖,那么下面的代码可能也会起作用,感谢您伸出:

serverData.getData().then(function(response) {
    $scope.gridOptions.data = response.data[0];
    $scope.sitesData = response.data[1];

    // You may have to shape data in a method before doing the next line
    // ex: var sitesArray = shapeSitesData();

    $scope.gridOptions.columnDefs[13].editDropdownOptionsArray = $scope.sitesData;
});

Since Stackoverflow doesn't respect new people's opinions I cannot comment on your thread with transistor. 由于Stackoverflow不尊重新人的意见,我不能用晶体管评论你的线程。 Hopefully you see this as I believe it will help. 希望你看到这一点,因为我相信它会有所帮助。 The issue you are encountering could also be due to the fact that ui-grid doesn't do a great job of mapping ids and values. 您遇到的问题也可能是由于ui-grid在映射ID和值方面做得不好。 You should try my variant (which i believe improves upon @mltroutt's solution). 你应该尝试我的变体(我相信改进@ mltroutt的解决方案)。

angular.module('app')
     .controller('yourctrl', yourFunction)
     .filter('griddropdown', function () {
    return function (input, context) {
        var fieldLevel = (context.editDropdownOptionsArray == undefined) ? context.col.colDef : context;
        var map = fieldLevel.editDropdownOptionsArray;
        var idField = fieldLevel.editDropdownIdLabel;
        var valueField = fieldLevel.editDropdownValueLabel;
        var initial = context.row.entity[context.col.field];
        if (typeof map !== "undefined") {
            for (var i = 0; i < map.length; i++) {
                if (map[i][idField] == input) {
                    return map[i][valueField];
                }
            }
        }
        else if (initial) {
            return initial;
        }
        return input;
    };

Then add this to your coldef 然后将此添加到您的coldef

cellFilter: 'griddropdown:this'

It's a timing issue. 这是一个时间问题。 At the point where you're calling alert(sitesD) , your data hasn't loaded yet. 在您调用alert(sitesD) ,您的数据尚未加载。 Angular promises are asynchronous, which is what the then statement is for. Angular promises是异步的,这就是then语句的用法。

If you move your alert inside the then , your dropdown data should appear: 如果您在then移动警报,则应显示下拉数据:

serverData.getData().then(function(response) {
        $scope.gridOptions.data = response.data[0];
        $scope.sitesData = response.data[1];
        alert($scope.sitesData);
});

If it's still undefined, either response.data[1] doesn't contain your data, or you've got a problem with your server-side logic. 如果它仍未定义,则response.data [1]不包含您的数据,或者您的服务器端逻辑出现问题。

If your data does appear correctly in the then alert, next try changing editDropdownOptionsArray: $scope.sitesData 如果您的数据确实在then警报中正确显示,请尝试更改editDropdownOptionsArray: $scope.sitesData

Edit: in my solution, I use an angular-resource instead of $http, and it works as described above. 编辑:在我的解决方案中,我使用角度资源而不是$ http,它的工作原理如上所述。 You may want to try this, though I'd expect it to work the way you've coded it with $http as well. 你可能想试试这个,虽然我希望它能以你用$ http编码的方式工作。

angular.module('siteDataService', ['ngResource'])
.factory('siteData', function($resource) {
  return $resource('/workers', {}, {
    query: { method:'GET', isArray: true }
  }
});

Make sure you include angular-resource.js in your HTML, and take a dependency on siteDataService in your application, and add siteData in your controller. 确保在HTML中包含angular-resource.js ,并在应用程序中依赖siteDataService ,并在控制器中添加siteData

To run the query, you'd use $scope.serverResponse = siteData.query(); 要运行查询,您需要使用$scope.serverResponse = siteData.query(); in the body of your controller. 在你的控制器的身体。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM