javascript - Angular UI-Grid - 当自定义指令更新单元格值时,afterCellEdit 事件不会触发

标签 javascript angularjs datepicker angular-ui-grid

我使用 AngularJS 1.5.0 和 UI-Grid 3.1.1 开发 Web 应用程序。

我需要具有跨浏览器日期选择器的列,因此我决定使用 Bootstrap-Datepicker ( https://github.com/eternicode/bootstrap-datepicker )。

对于本专栏,我使用 customTemplate:

rejestrator.columnTemplates.dayCellEditable =
'<div class="column-day">' +
    '<span ng-model="row.entity.day" ng-change="updateDayCell(row, row.entity.day)" aa-date-input>{{ COL_FIELD | date:"yyyy-MM-dd" }}</span>'+
'</div>';

当我单击日期单元格时,日期选择器会被正确调用,它甚至会使用所选数据更新行中的单元格,但不幸的是,没有触发 UpdateDayCell (ng-change) 函数,甚至没有触发 gridApi.edit.on.afterCellEdit...

我需要触发 updateDayCell Controller 的函数或触发事件来监听 on.afterCellEdit 以发送更新数据库的请求。

我的网格定义是:

$scope.myTaskGridOptions = {
    exporterMenuCsv: false,
    enableGridMenu: true,
    enableSorting: true,
    enableFiltering: false,
    enableCellEditOnFocus: true,
    columnDefs: [
        {
            name: 'Dzień', 
            field: 'day', 
            width: '130',
            sort: { direction: 'asc', priority: 0 }, 
            type: 'date',
            cellFilter: 'date:\'yyyy-MM-dd\'',
            cellTemplate: rejestrator.columnTemplates.dayCellEditable, 
            enableCellEdit:false
        },
        {
            name: 'Projekt',
            field: 'project_name', 
            editableCellTemplate: 'ui-grid/dropdownEditor',
            width: '15%', 
            editDropdownOptionsFunction : MyTasksProvider.getMyProjects
        },
        { 
          name: 'Opis',  
          field: 'description', 
          width: '50%' 
          },
        {
            name: 'Czas',      
            field: 'used_time' , 
            width: '75', 
            type: 'string',
            cellTemplate: rejestrator.columnTemplates.timeCell,
            enableCellEdit: false
        },
        {
          name: 'Akcje',
          field: 'id',
          enableSorting: false,  
          width: '90', 
           cellTemplate: rejestrator.columnTemplates.actionsCell,
          displayName: '',
          enableColumnMenu:false, 
          enableCellEdit: false
        }
    ],
    //Bind events
    onRegisterApi : function(gridApi){
        $scope.gridApi = gridApi;
        gridApi.edit.on.afterCellEdit($scope,function(rowEntity, colDef, newValue, oldValue){
            if (newValue !== oldValue) {
                var callback = function(){};
                var fieldToChange = colDef.field,
                    valueToSet = newValue;
                if (fieldToChange === 'project_name') {
                    fieldToChange = 'project_id';
                    callback = refreshGrid;
                } else if (fieldToChange == 'day') {
                    valueToSet = $filter('date')(newValue, "yyyy-MM-dd");
                    rowEntity.day = valueToSet;
                }
                CommonTasksProvider.updateTaskFieldByID(rowEntity.id, fieldToChange, valueToSet, callback);
            }
        });
        //gridApi.core.on.filterChange
    },
    //Disable multiselection
    multiSelect: true
};

grid

编辑:

我添加了对设置值时由 Datepicker 触发的事件“aa:calendar:set-date”的监视:

$scope.$on('aa:calendar:set-date', function(event, toState, toParams, fromState, fromParams){
    var dateObj = event.targetScope.$parent.ngModel,
        day = $filter('date')(dateObj, "yyyy-MM-dd"),
        taskId = event.targetScope.$parent.taskId;
    return CommonTasksProvider.updateTaskFieldByID(taskId, 'day', day)
});

而且它有效。各位,您认为这是一个好的解决方案吗? Angular 路?或者性能可能会很昂贵?

最佳答案

我使用了ui.bootstrap.datetimepicker:

var dateCellTemplate = 
                            ' <div layout="row" >' +
                            '    <wm-ai-grid-date-picker class="wm-ai-standalone-due-date"' +
                            '        data-ng-model="row.entity.timestamp_due"' +
                            '    ></wm-ai-grid-date-picker>' +
                            '</div>';

这是我的指令,(希望对您有帮助):

app.directive('wmAiGridDatePicker', ['$timeout','$parse', function ($timeout, $parse) {
        return {//this datePicker will show the date in the wanted format and save it (ng-model) with the default format of yy-mm-dd
            template: '<input type="text"  style="cursor: pointer;border-color: rgb(239, 239, 239);height: 22px;padding-left: 6px;margin-right: 13px;margin-top: 10px;">',

            replace: true,
            require: 'ngModel',
            scope: {},
            link: function (scope, element, attrs, controller) {

                scope.time = {
                    hours: 0,
                    minutes: 0
                };

                var getModel = function () {
                     return controller.$modelValue;
                };

                var options = {
                   format: "dd/mm/yyyy"
                    ,autoclose: 'true'
                    //,startDate: $filter('date')(new Date().getTime(), 'dd/mm/yyyy')
                    //,startDate: "10/04/2015"
                    ,todayBtn: "linked"
                };

                element.datepicker(options);

                element.datepicker().on('hide', function () {

                    $timeout(function () {
                        var date_ = element.datepicker('getDate');

                        if(date_){
                            date_.setHours(scope.time.hours);
                        date_.setMinutes(scope.time.minutes);
                        //controller.$setViewValue(date_);
                        controller.$setViewValue(moment(date_).unix());
                        }


                        scope.$apply();
                    }, 1);
                });

                element.datepicker().on('changeDate', function () {

                    $timeout(function () {
                        var date_ = element.datepicker('getDate');

                        if(date_){
                            date_.setHours(scope.time.hours);
                        date_.setMinutes(scope.time.minutes);
                        //controller.$setViewValue(date_);
                        controller.$setViewValue(moment(date_).unix());
                        }


                        scope.$apply();
                    }, 1);

                });

                scope.onModelChange = function () {

                    console.log('onModelChange');

                    var date = controller.$modelValue;

                        if(angular.isDate(date)){
                            scope.time.hours = date.getHours();
                            scope.time.minutes = date.getMinutes();
                        }

//                    if (controller) {
//                        controller.$render();
//                     }
                };

               controller.$render = function () {
                        var unixDate = controller.$modelValue;

                        if(!unixDate){
                            return;
                        }

                        var date = new Date(unixDate * 1000);

                        if(angular.isDate(date)){
                            scope.time.hours = date.getHours();
                            scope.time.minutes = date.getMinutes();
                        }



//                        if (angular.isDefined(date) && date !== null && !angular.isDate(date)) {
//                            if (angular.isString(controller.$modelValue)) {
//                                date = controller.$modelValue; //uiDateConverter.stringToDate(attrs.uiDateFormat, controller.$modelValue);
//                            } else {
//                                throw new Error('ng-Model value must be a Date, or a String object with a date formatter - currently it is a ' + typeof date + ' - use ui-date-format to convert it from a string');
//                            }
//                        }
                        element.datepicker('setDate', date);
                        element.datepicker('update');
                    };

                scope.$watch(getModel, function (newVal) {
                   // if (typeof newVal !== undefined && newVal != null && newVal != "") {

                        scope.onModelChange();
                    //}
                }, true);


                if (controller) {
                    controller.$render();
                }
            }
        };
    }]);

关于javascript - Angular UI-Grid - 当自定义指令更新单元格值时,afterCellEdit 事件不会触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35790787/

相关文章:

angularjs - ng-repeat 过滤器在隐藏搜索文本字段后重置

javascript - AngularJS: Controller 之间的数据传递和范围问题

javascript - jQuery Datepicker - 选择日期之一时在输入字段中插入数据

javascript - Bootstrap UI 日期选择器的无效 "ng-model"值

javascript - jquery AJAX 中的 slideDown 传入数据

javascript - .each() 不循环所有元素 - jQuery

javascript - 带有 Javascript 动画背景的 HTML 如何在其上获取 div?

javascript - 没有下拉菜单的 Bootstrap 导航栏下拉表

javascript - Angular/Ionic 和异步 SQLite - 确保数据工厂在返回前初始化

jquery - 使用 Materialize 从今天开始的默认日期为一年前