-->

AngularJS和NG-网 - 汽车电池更改后的数据保存到服务器(AngularJS and ng

2019-07-25 04:17发布

我用例是非常简单的。 一个用户,编辑单元格(enableCellEdit:真)后,应具有数据“自动地”发送到服务器(对细胞模糊)。 我尝试不同的方法,但他们都没有妥善解决。 我有一个简约的网格:

// Configure ng-grid
$scope.gridOptions = {
    data: 'questions',
    enableCellSelection: true,
    selectedItems: $scope.selectedRow,
    multiSelect: false,
    columnDefs: [
        {field: 'id', displayName: 'Id'},
        {field: 'name', displayName: 'Name'},
        {field: 'answers[1].valuePercent', displayName: 'Rural', enableCellEdit: true}
    ]
};

例如,我试图观看传递给电网的数据模型。 但这样做不会回到我所编辑的单元格:

$scope.$watch('myData', function (foo) {
    // myModel.$update()
}, true);

我试着用“ngGridEventData”数据事件摆弄,但它的细胞编辑后不火

$scope.$on('ngGridEventData', function (e, gridId) {
    // myModel.$update()
});

最后,我想观察者细胞。 然而,这只是一个排由网格的“selectedCell”属性的平均工作:

$scope.selectedRow = [];

$scope.gridOptions = {
    selectedItems: $scope.selectedRow,
}

$scope.$watch('selectedRow', function (foo) {
    console.log(foo)
}, true);

它是一个NG-网格插件需要的? 我不能相信这是不是开箱。

你有一个指针/片断我怎么能解决这个自动保存/发送到服务器?

Answer 1:

也许这是新的,但NG-电网实际发布可用于实现对变化的简单更新事件。

事件参考: https://github.com/angular-ui/ng-grid/wiki/Grid-Events

示例代码(添加到控制器,其中在安装网格):

$scope.$on('ngGridEventEndCellEdit', function(evt){
    console.log(evt.targetScope.row.entity);  // the underlying data bound to the row
    // Detect changes and send entity to server 
});

有一点需要注意的是,如果没有修改过的事件仍将触发,所以你可能还是要发送到服务器之前检查更改(通过“ngGridEventStartCellEdit”为例)



Answer 2:

我发现我的想法是一个好得多的解决方案:

  cellEditableTemplate = "<input ng-class=\"'colt' + col.index\" ng-input=\"COL_FIELD\" ng-model=\"COL_FIELD\" ng-change=\"updateEntity(row.entity)\"/>"

采用NG-改变这种方式会导致updateEntity与已经改变了整个对象(行)被调用,您可以将它张贴回服务器。 你不需要任何新的范围变量。 以前的解决方案的缺陷是,当您点击开始编辑领域,这将永远是空白的,而不是原来的价值,你就开始编辑之前。

这将导致updateEntity()被调用每个按键。 如果这是对你来说太频繁,你可以发布到服务器之前使用超时,或只是使用updateEntity()来记录你要推,然后用NG-模糊后记录的ID与id。



Answer 3:

它看起来我找到了一个解决方案感谢角的邮件列表 。 有人指出的是AngularJS缺少onblur事件(还有的onfocus)。 然而,这可以通过添加一个“简单”的指令来克服。

angular.module('myApp.ngBlur', [])
.directive('ngBlur', function () {
    return function (scope, elem, attrs) {
        elem.bind('blur', function () {
            scope.$apply(attrs.ngBlur);
        });
    };
});

随着信息,还有相关的模糊事件指令执行的另一个例子在这里 。

然后,在控制器的代码的其余部分是这样的:

// Define the template of the cell editing with input type "number" (for my case).
// Notice the "ng-blur" directive
var cellEditableTemplate = "<input style=\"width: 90%\" step=\"any\" type=\"number\" ng-class=\"'colt' + col.index\" ng-input=\"COL_FIELD\" ng-blur=\"updateEntity(col, row)\"/>";

// Configure ng-grid
$scope.gridOptions = {
    data: 'questions',
    enableCellSelection: true,
    multiSelect: false,
    columnDefs: [
        {field: 'id', displayName: 'Id'},
        {field: 'name', displayName: 'Name'},

        // Notice the "editableCellTemplate"
        {field: 'answers[0].valuePercent', displayName: 'Rural', enableCellEdit: true, editableCellTemplate: cellEditableTemplate}
    ]
};


// Update Entity on the server side
$scope.updateEntity = function(column, row) {
    console.log(row.entity);
    console.log(column.field);

    // code for saving data to the server...
    // row.entity.$update() ... <- the simple case

    // I have nested Entity / data in the row <- the complex case
    // var answer = new Answer(question.answers[answerIndex]); // answerIndex is computed with "column.field" variable
    // answer.$update() ...
}


Answer 4:

我花了一些时间的这个位汇集了NG-电网2.x版本 我仍然有不必点击两次编辑一排的问题,但我认为这是一个引导的问题,不是一个ngGrid问题,它不会在我的示例代码发生(它没有引导至今)。

我也为UI电网3.0,它仍然是测试阶段,但很快将成为首选版本的教程来实现类似的逻辑。 这可以在这里找到: http://technpol.wordpress.com/2014/08/23/upgrading-to-ng-grid-3-0-ui-grid/ ,并提供了一个更容易和更简洁的API实现此功能。

对于2.x版,说明所有的位,我已经创建了一个具有可编辑的网格既具有下拉菜单和输入字段中的运行plunker,采用ngBlur指令,并使用$超时,避免重复的节省更新: http://plnkr.co/edit/VABAEu?p=preview

代码的基础是:

var app = angular.module('plunker', ["ngGrid"]);

app.controller('MainCtrl', function($scope, $timeout, StatusesConstant) {
  $scope.statuses = StatusesConstant;
  $scope.cellInputEditableTemplate = '<input ng-class="\'colt\' + col.index" ng-input="COL_FIELD" ng-model="COL_FIELD" ng-blur="updateEntity(row)" />';
  $scope.cellSelectEditableTemplate = '<select ng-class="\'colt\' + col.index" ng-input="COL_FIELD" ng-model="COL_FIELD" ng-options="id as name for (id, name) in statuses" ng-blur="updateEntity(row)" />';

  $scope.list = [
    { name: 'Fred', age: 45, status: 1 },
    { name: 'Julie', age: 29, status: 2 },
    { name: 'John', age: 67, status: 1 }
  ];

  $scope.gridOptions = {
    data: 'list',
    enableRowSelection: false,
    enableCellEditOnFocus: true,
    multiSelect: false, 
    columnDefs: [
      { field: 'name', displayName: 'Name', enableCellEditOnFocus: true, 
        editableCellTemplate: $scope.cellInputEditableTemplate },
      { field: 'age', displayName: 'Age', enableCellEdit: false },
      { field: 'status', displayName: 'Status', enableCellEditOnFocus: true, 
        editableCellTemplate: $scope.cellSelectEditableTemplate,
        cellFilter: 'mapStatus'}
    ]
  };

  $scope.updateEntity = function(row) {
    if(!$scope.save) {
      $scope.save = { promise: null, pending: false, row: null };
    }
    $scope.save.row = row.rowIndex;
    if(!$scope.save.pending) {
      $scope.save.pending = true;
      $scope.save.promise = $timeout(function(){
        // $scope.list[$scope.save.row].$update();
        console.log("Here you'd save your record to the server, we're updating row: " 
                    + $scope.save.row + " to be: " 
                    + $scope.list[$scope.save.row].name + "," 
                    + $scope.list[$scope.save.row].age + ","
                    + $scope.list[$scope.save.row].status);
        $scope.save.pending = false; 
      }, 500);
    }    
  };
})

.directive('ngBlur', function () {
  return function (scope, elem, attrs) {
    elem.bind('blur', function () {
      scope.$apply(attrs.ngBlur);
    });
  };
})

.filter('mapStatus', function( StatusesConstant ) {
  return function(input) {
    if (StatusesConstant[input]) {
      return StatusesConstant[input];
    } else {
      return 'unknown';
    }
  };
})

.factory( 'StatusesConstant', function() {
  return {
    1: 'active',
    2: 'inactive'
  };
});

当你运行这个plunker,而失去焦点火灾,你应该看到控制台更新触发器触发的。

我用的东西给了我的困难,在这里转载一些想法plunker也包括README.md。

这里的功能是,我的人的名单,这些人的姓名,年龄和状态。 在与我们可能会在真正的应用程序做线,状态是一个代码,我们要显示的解码。 因此,我们有一个状态码列表(可能在真正的应用程序来自数据库),我们有一个过滤器的代码映射到解码。

我们要的是两件事情。 我们希望能够在输入框中编辑名称,以及编辑在下拉状态。

对事情的评论我已经学会在这个普拉克。

  1. 在gridOptions水平,既有enableCellEditOnFocus和enableCellEdit。 不要同时启用,你需要选择。 聚焦状态是指单一的点击,CellEdit指双击。 如果同时启用,那么你得到你的网格位意外的行为,你不想为可编辑

  2. 在columnDefs水平,你有相同的选项。 但是,这个时候你需要同时设置CellEdit和聚焦状态,你需要cellEdit设为您不希望任何编辑过的细胞假 - 这是不是默认

  3. 该文件说,您可编辑单元模板可以是:

    <输入纳克级= “ '小马' + col.index” NG-输入= “COL_FIELD”/>

    实际上它需要:

    <输入纳克级= “ '小马' + col.index” NG-输入= “COL_FIELD” NG-模型= “COL_FIELD”/>

  4. 要触发保存事件,当我们失去焦点,我们已经创建了一个模糊的指令,为此,我在计算器中发现的逻辑: AngularJS和NG-格-自动将数据保存到服务器的细胞被改变后,

  5. 这也意味着改变每个编辑单元模板调用NG-模糊,您可以在编辑单元模板年底见

  6. 我们得到两个模糊事件,当我们离开现场(至少在铬),所以我们用一个定时器,使得只有其中一个被处理。 丑陋,但它的工作原理。

我还创建了一个博客贴子,这段代码进行更彻底的演练: http://technpol.wordpress.com/2013/12/06/editable-nggrid-with-both-dropdowns-and-selects/



Answer 5:

如果您使用的UI电网3.0事件:uiGridEventEndCellEdit

$scope.$on('uiGridEventEndCellEdit', function (data) {
    console.log(data.targetScope.row.entity);
}


Answer 6:

这是一种改进,其中有一些缺陷的答案: - 它触发JS例外,在答案的评论一个表示 - 在单元格中输入的数据不保留在电网 - 的updateEntity方法没有说明如何保存输入数据

为了消除异常,创建一个作用域属性,并将其添加到cellEditableTemplate:

$scope.cellValue;
...
var cellEditableTemplate = "<input style=\"width: 90%\" step=\"any\" type=\"number\" ng-class=\"'colt' + col.index\" ng-input=\"COL_FIELD\" ng-blur=\"updateEntity(col, row, cellValue)\" ng-model='cellValue'/>";

请注意,NG-模糊调用updateEntity现在包括cellValue作为参数。 下一步,更新updateEntity模糊处理程序,包括参数和更新的网格:

$scope.updateEntity = function(column, row, cellValue) {
    console.log(row.entity);
    console.log(column.field);
    row.entity[column.field] = cellValue;

    // code for saving data to the server...
    // row.entity.$update() ... <- the simple case

    // I have nested Entity / data in the row <- the complex case
    // var answer = new Answer(question.answers[answerIndex]); // answerIndex is computed with "column.field" variable
    // answer.$update() ...
};

我现在能在屏幕上看到的变化以及引发细胞为基础的后台更新。



Answer 7:

由于包贵革在评论UI网格中提及了目前拥有设计完成编辑后,让整个行的储蓄rowEdit功能。 见http://ui-grid.info/docs/#/tutorial/205_row_editable 。



文章来源: AngularJS and ng-grid - auto save data to the server after a cell was changed