上一篇博客总结了一下在dataForm中遇到的save问题,同样在DataGrid里面save方法也有同样的问题,先把问题说一下。
在DataGrid保存的时候(使用的是btnSave_onclick)如果某一列的数据没有修改那么在UAP向后台传递数据的时候这列数据就不会传递到后台,而在我负责的模块中就需要把父表的ID传递到后台,当然并不是所有的列都可以添加ID的,这就需要添加一些校验而校验不通过的时候就会return或者return false,UAP还会继续调用save方法还会继续向后台发送请求和错误数据,这样就造成数据错误了。
下面是我在项目中写的DataGrid的保存
me._buttonSave_onclick = function(){
me.view.getDataGrid().clearEditor();
var reportId = me.view.reportId;
var grid = me.view.getDataGrid();
var totalLength = grid.items.length;
var item = null;
var isSave = true;
for (var i = 0; i < totalLength; i++) {
item = grid.items[i];
var dutyName = item.getValue("dutyName");
var dutyDesc = item.getValue("dutyDesc");
var dutySkill = item.getValue("dutySkill");
if(dutyName =="" || dutyName == null){
mx.indicate("info", "职责名称必须输入!");
isSave = false;
break;
}else if(dutyName.getByteCount() > 500 ){
mx.indicate("info", "职责名称长度不能超过500!");
isSave = false;
break;
}
grid.entityContainer.setValue(grid.entityContainer.getEntityByIndex(i),"reportId",reportId);
}
if(isSave){
grid.entityContainer.save();
}};
这段代码的保存方法是没有问题的,把return false 换为修改一个变量的值通过这个值来判断是否调用 grid.entityContainer.save()方法,这样就不用在去调用grid的save方法了。不过这样就又出现了一个问题:在grid的新增一列值的时候,在单元格输入完成以后光标继续停留在这个单元格里面直接去点击save的时候它会提示这个单元格没有输入内容。不过在使用btnSave_onclick的时候就不会出现这个问题。后来通过查看DataGrid的源码找到了一个方法me.view.getDataGrid().clearEditor()也就是代码中标红部分.
在点击保存的时候如果光标不停留在单元格内保存方法就会顺利执行,想屏蔽上面js代码中的问题就需要在保存之前移除单元格的光标。如何移除呢?想到的方法是blur,但是如何去判断到底上哪一个单元格需要失去焦点呢?精确到单元格做不到那就需要遍历和循环了。当通过firefox的firebug调试一段时间以后发现这个问题还不是太容易解决,在我能看到的属性和方法中我实现我的目标。所以目光又再一次找到源码上。
下面是DataGrid.js的代码:
var _saveCallBack = null; /** * 向 {@link mx.datacontainers.EntityContainer} 请求保存数据。 * * @param [p_data = null] 一个 JSON 对象,表示用户自定义需要保存的参数。 * @param [p_callback = null] 一个回调的函数。 */ me.save = function(p_data, p_callback) { me.clearEditor(); var data = null; if ($notEmpty(p_data) && $isFunction(p_data)) { p_callback = p_data; data = null; } else if ($notEmpty(p_data) && $isPlainObject(p_data)) { data = p_data; } if ($notEmpty(p_callback)) { _saveCallBack = p_callback; } else { _saveCallBack = null; } if ($notEmpty(me.entityContainer)) { _requestEntityContainer(data, "save"); } };
me.clearEditor = function(e) { if (!_editing || $isEmpty(_editingItem)) { return; } var editor = _columnEditors.getItem(_editingCloumnName); //如果编辑器的校验没通过,则不清除,并返回false; if(!editor.isValidate) { editor.focus(); return false; } // 解决富文本编辑器在编辑状态,工具栏的点击可能使编辑器清除问题 if ($instanceOf(editor, mx.editors.RichTextEditor) && editor.editing) { return false; } if ($instanceOf(editor, mx.editors.ComboEditor)) { var target = null; if ($notEmpty(e)) { target = e.target; } if ($isEmpty(target) || !editor.contains(target)) { editor.hideDropDown(); } else { return; } } var rowItem = _editingItem; var value = editor.value; var $td = editor.$e.parent(); var column = _getTdColumn($td); if($notEmpty(me.entityContainer)) { var keyVal = _editingItem.values[me.primaryKey]; if ($notEmpty(me.entityContainer.getEntityByKey(keyVal))) { var oldVal = me.entityContainer.getEntityByKey(keyVal)[_editingCloumnName]; if (oldVal == value) { me._changeEditorToText(_editingCloumnName); } else { me.entityContainer.setValue(keyVal, column.name, value, true); } } } else { editor.$e.detach(); if ($notEmpty(column)) { column.renderCell(_editingItem, $td); } _editingItem = null; } $td.removeClass("editing"); me.trigger("celledited", {column: column, item: rowItem, cell: $td}); _editing = false; };
在datagird中发现clearEditor这个方法,然后我就尝试着使用这个方法结果发现问题就解决了。当然后来这个属性在API中也有,但是当时看的时候没有看明白在看源码和遇到问题以及解决问题的时候也了解了这个属性。