AngularJS 및 ng-grid - 셀 변경 후 데이터를 서버에 자동 저장
사용 사례는 매우 간단합니다.셀을 편집한 후(enableCellEdit: true), 데이터를 자동으로 서버로 전송해야 합니다(셀이 흐려짐).여러 가지 방법을 시도해 보았지만 제대로 된 방법이 하나도 없었다.나는 미니멀리즘 그리드를 가지고 있다.
// 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()
});
마침내, 나는 감방을 관찰하려고 했다.단, 이는 그리드의 "selected Cell" 속성의 평균에 의한 행에만 적용됩니다.
$scope.selectedRow = [];
$scope.gridOptions = {
selectedItems: $scope.selectedRow,
}
$scope.$watch('selectedRow', function (foo) {
console.log(foo)
}, true);
ng-grid 플러그인이 필요합니까?나는 그것이 기성품이 아니라는 것을 믿을 수 없다.
서버에 자동 저장/전송을 해결할 수 있는 포인터/스니펫이 있습니까?
새로운 것일 수도 있지만 ng-grid는 실제로 변경 시 간단한 업데이트를 구현하기 위해 사용할 수 있는 이벤트를 게시합니다.
이벤트 레퍼런스: 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' 사용).
저는 제가 생각하는 훨씬 더 좋은 해결책을 찾았습니다.
cellEditableTemplate = "<input ng-class=\"'colt' + col.index\" ng-input=\"COL_FIELD\" ng-model=\"COL_FIELD\" ng-change=\"updateEntity(row.entity)\"/>"
이 방법으로 ng-change를 사용하면 변경된 오브젝트(행) 전체가 updateEntity에 호출되어 서버에 다시 게시할 수 있습니다.새로운 범위 변수는 필요 없습니다.이전 솔루션의 단점은 필드 편집을 시작하기 위해 클릭했을 때 필드를 편집하기 전에 원래 값이 아닌 항상 비어 있다는 것입니다.
그러면 각 키 입력에서 updateEntity()가 호출됩니다.이것이 너무 자주 발생하는 경우 서버에 게시하기 전에 타임아웃을 사용하거나 updateEntity()를 사용하여 푸시할 ID를 기록한 후 ng-blur를 사용하여 기록된 ID를 게시할 수 있습니다.
Angular 메일링 리스트 덕분에 해결책을 찾은 것 같습니다.Angular가 지목된 것은JS에 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() ...
}
ng-grid 2.x의 경우 이 부분을 정리하는 데 시간이 걸렸습니다.행을 편집하기 위해 두 번 클릭해야 하는 문제는 여전히 있지만, 이는 부트스트랩 문제이지 ngGrid 문제가 아니라고 생각합니다. 샘플 코드(부트스트랩은 아직 없습니다)에서는 발생하지 않았습니다.
저는 ui-grid 3.0의 튜토리얼에도 비슷한 로직을 실장했습니다.이것은 아직 베타판이지만 곧 선호 버전이 될 것입니다.이 기능은 http://technpol.wordpress.com/2014/08/23/upgrading-to-ng-grid-3-0-ui-grid/,에서 확인할 수 있으며, 이 기능을 위해 훨씬 쉽고 깔끔한 API를 제공합니다.
2.x 버전에서는 모든 비트를 표시하기 위해 드롭다운 필드와 입력 필드 모두 편집 가능한 그리드를 가진 실행 중인 플런커를 작성했습니다.ngBlur 디렉티브를 사용하고 업데이트 시 중복 저장을 피하기 위해 $120을 사용합니다.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'
};
});
이 플런커를 실행하고 포커스를 잃으면 콘솔에 업데이트트리거 부팅이 표시됩니다.
또한 README.md를 플런커에 포함시켰습니다.여기서 재현한 것처럼, 곤란했던 것에 대해 몇 가지 생각을 하고 있습니다.
여기서 기능하는 것은 이름, 나이 및 지위를 가진 사람 목록이 있다는 것입니다.실제 앱에서 수행할 수 있는 작업에 따라 상태는 코드이며 디코딩을 보여 줍니다.따라서 상태 코드 목록(실제 앱의 경우 데이터베이스에서 가져올 수 있음)과 코드를 디코딩에 매핑하는 필터가 있습니다.
우리가 원하는 건 두 가지야입력란에서 이름을 편집하고 드롭다운에서 상태를 편집할 수 있도록 하고 싶습니다.
이 플렁크에서 배운 거에 대한 댓글.
gridOptions 레벨에는 enableCellEditOnFocus와 enableCellEdit이 있습니다.둘 다 활성화하지 말고 선택해야 합니다.onFocus는 원클릭, CellEdit은 더블클릭을 의미합니다.둘 다 활성화하면 그리드의 비트에서 편집하고 싶지 않은 예기치 않은 동작이 발생합니다.
columnDefs 수준에서도 동일한 옵션을 사용할 수 있습니다.그러나 이번에는 CellEdit과 onFocus를 모두 설정해야 하며 편집하지 않는 셀에서는 cellEdit을 false로 설정해야 합니다.기본값이 아닙니다.
매뉴얼에서는 편집 가능한 셀템플릿은 다음과 같습니다.
<input ng-class='colt' + col.인덱스" ng-input="COL_FILD" />
실제로 필요한 것은 다음과 같습니다.
<input ng-class='colt' + col.인덱스" ng-input="COL_FILD" ng-model="COL_FILD" />
초점을 잃었을 때 저장 이벤트를 트리거하기 위해 stackoverflow에서 찾은 논리인 흐림 지시문을 만들었습니다.각진JS 및 ng-grid - 셀 변경 후 데이터를 서버에 자동 저장
이는 편집 가능한 셀템플릿의 끝에 표시되는 각 편집 가능한 셀템플릿을 ng-blur로 변경하는 것을 의미합니다.
(최소한 Chrome에서는) 필드를 벗어나면 2개의 흐림 현상이 발생하므로 타이머를 사용하여 1개만 처리됩니다.못생겼지만, 효과가 있어요.
또, 이 코드의 상세한 것에 대해 설명하는 블로그 투고도 작성했습니다.http://technpol.wordpress.com/2013/12/06/editable-nggrid-with-both-dropdowns-and-selects/
UI Grid 3.0을 사용하는 경우 해당 이벤트는 다음과 같습니다.uiGridEventEndCellEdit
$scope.$on('uiGridEventEndCellEdit', function (data) {
console.log(data.targetScope.row.entity);
}
이는 몇 가지 결함이 있는 답변에 대한 개선 사항입니다. - 답변의 코멘트 중 하나에 표시된 바와 같이 JS 예외를 트리거합니다. 셀의 데이터 입력은 그리드에 유지되지 않습니다. updateEntity 메서드는 입력 데이터를 저장하는 방법을 설명하지 않습니다.
예외를 삭제하려면 스코프 속성을 생성하여 cellEditable에 추가합니다.템플릿:
$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'/>";
여기서 updateEntity에 대한 ng-blur 호출에는 인수로서 cellValue가 포함되어 있습니다.다음으로 인수를 포함하도록 updateEntity blur 핸들러를 업데이트하고 그리드를 업데이트합니다.
$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() ...
};
이제 화면에서 변경 사항을 볼 수 있을 뿐만 아니라 셀 기반 백엔드 업데이트를 트리거할 수 있습니다.
코멘트 중 하나에서 언급한 바와 같이 ui-grid에는 편집이 완료되면 행 전체를 저장할 수 있도록 설계된rowEdit 기능이 있습니다.http://ui-grid.info/docs/ #/syslogs/syslogs_row_syslogs 를 참조하십시오.
언급URL : https://stackoverflow.com/questions/15647981/angularjs-and-ng-grid-auto-save-data-to-the-server-after-a-cell-was-changed
'source' 카테고리의 다른 글
| PHP가 JSON을 JQUERY AJAX 호출로 반환 (0) | 2023.03.28 |
|---|---|
| JSON 스키마에 선언된 속성만 허용 (0) | 2023.03.28 |
| IIS를 통해 제공되는 단일 페이지 응용 프로그램 HTML 파일의 캐시를 비활성화하려면 어떻게 해야 합니까? (0) | 2023.03.28 |
| create-react-app을 사용할 때 사용자 지정 빌드 출력 폴더 사용 (0) | 2023.03.28 |
| JavaScript: Ajax 요청 후 글로벌 변수 (0) | 2023.03.28 |