Dưới đây là một số lời khuyên để giải quyết vấn đề chính của bạn và cải thiện mã JavaScript mà bạn đã đăng.
Trước hết, thế hệ hàng chèo mới cục bộ là cần thiết cho kịch bản chỉnh sửa cục bộ. Người ta sẽ tạo các rowid mới trên máy chủ trong trường hợp lưu dữ liệu trên phụ trợ trong cơ sở dữ liệu. Cách triển khai điển hình bao gồm việc có PRIMARY KEY
được định nghĩa là int IDENTITY
trong mọi bàn. Nó làm cho id duy nhất và cố định. Việc xóa một số hàng và tạo một hàng mới sẽ không bao giờ được hiểu là chỉnh sửa hàng cũ vì hàng mới sẽ luôn nhận được id mới, id này chưa bao giờ được sử dụng trước đây (trong bảng).
Để tận dụng lợi thế của id được tạo trên phía máy chủ người ta có hai lựa chọn chính:
- tải lại lưới sau mỗi thao tác Thêm hàng.
- mở rộng giao tiếp với máy chủ khi chỉnh sửa để máy chủ trả về id mới, được tạo trong bảng cơ sở dữ liệu, trở lại jqGrid. Người ta có thể sử dụng
aftersavefunc
gọi lại (chỉ dành cho Thêm hàng mới) để cập nhật rowid sau khi tạo thành công hàng trên máy chủ. Nhiều triển khai tiêu chuẩn của các dịch vụ RESTful trả về dữ liệu hàng đầy đủ id bao gồm cả Thêm hoặc Chỉnh sửa. Người ta có thể sử dụng dữ liệu bên trongaftersavefunc
gọi lại và sử dụng một cái gì đó như$("#" + rowid).attr("id", newRowid);
để cập nhật hàng mới. Nó đã lưu id trong một số cột bổ sung (giống như bạn sử dụngid
ẩn cột) thì người ta nên sử dụngsetCell
bổ sung để cập nhật ô.
Lựa chọn đầu tiên hầu hết là đơn giản và tôi khuyên bạn nên thực hiện nó trước. Chỉ khi việc tải lại lưới sẽ không làm hài lòng người dùng, những người lần lượt thêm nhiều hàng, thì bạn nên viết thêm một chút mã và để thực hiện kịch bản thứ hai.
Mã hiện tại của bạn sử dụng inlineNav
cho các hoạt động Thêm và Chỉnh sửa, được triển khai bằng cách sử dụng chỉnh sửa nội tuyến và phương pháp navGrid
cho hoạt động Xóa, được triển khai bằng cách sử dụng chỉnh sửa biểu mẫu. Chỉnh sửa biểu mẫu, bao gồm Xóa, sử dụng reloadAfterSubmit: true
tùy chọn theo mặc định. Có nghĩa là lưới sẽ được tải lại từ máy chủ (từ url: "/RestWithDatabaseConnection/rest/fetchData"
) sau khi xóa mọi hàng. Bạn có thể giải quyết vấn đề chính của mình bằng cách thay thế afterSaveFunction
như sau:
var afterSaveFunction = function () {
$(this).trigger("reloadGrid", [{current: true, fromServer: true}]);
};
Tùy chọn current
để giữ lựa chọn hiện tại sau khi tải lại và tùy chọn fromServer: true
chỉ có ý nghĩa trong trường hợp bạn sử dụng loadonce: true
tùy chọn bổ sung. Bạn chỉ có thể sử dụng reloadGridOptions: {fromServer: true}
tùy chọn của navGrid
để buộc tải lại dữ liệu từ máy chủ khi nhấp vào nút Làm mới / Tải lại của thanh điều hướng. Nếu bạn không có quá nhiều dữ liệu mà bạn cần hiển thị trong lưới (ví dụ:ít hơn 1000 hàng) thì hành vi đó sẽ được khuyến nghị.
Một số lời khuyên phổ biến hơn dành cho bạn để cải thiện mã của bạn:
Bạn có thể cân nhắc sử dụng height: "auto"
thay vì height: 250
và để quản lý chiều cao tối đa của lưới bằng cách chỉ định rowNum
giá trị. Tùy chọn scrollOffset: 0
sẽ không cần thiết trong trường hợp này.
Định dạng của dữ liệu trả về từ máy chủ trông như vậy, do đó bạn không triển khai phân trang, sắp xếp và lọc phía máy chủ . Bạn nên sử dụng loadonce: true
và forceClientSorting: true
tùy chọn. loadonce: true
thông báo cho jqGrid để lưu tất cả dữ liệu được trả về cục bộ từ máy chủ trong dữ liệu data
tham số. Bạn có thể truy cập mảng bất kỳ lúc nào bằng cách sử dụng $('#grid').jqGrid("getGridParam", "data")
. Giá trị của rowNum
(giá trị mặc định là 20) sẽ được sử dụng cho cục bộ phân trang. sortname
và sortorder
sẽ được sử dụng cho địa phương sắp xếp. Và bạn sẽ sử dụng hộp thoại tìm kiếm (được thêm bởi navGrid
) hoặc thanh công cụ bộ lọc (được thêm bởi filterToolbar
) cho địa phương tìm kiếm / lọc. Nó đơn giản hóa mã máy chủ, cải thiện hiệu suất của lưới theo quan điểm của người dùng và đơn giản hóa giao diện giữa máy chủ và máy khách. Bạn có thể sử dụng giao diện RESTful cổ điển trên máy chủ mà không cần bất kỳ tiện ích mở rộng nào.
Một nhận xét khác:Tôi khuyên bạn nên xóa id
ẩn không cần thiết cột (name:'id', label:'id', key: true, hidden: true, ...
). Thông tin về rowid sẽ được lưu trong id
thuộc tính của các hàng (<tr>
phần tử) và một người không cần giữ thông tin trùng lặp trong <td>
ẩn trong mọi hàng.
Có nhiều phần khác trong mã của bạn, có thể được cải thiện. Ví dụ:thao tác DELETE mà bạn sử dụng ở phía máy chủ có vẻ lạ. Bạn sử dụng mtype: 'DELETE'
, nhưng bạn gửi id của hàng đã xóa bên trong body của yêu cầu tới máy chủ thay vì gắn nó vào URL. Tương ứng với các tiêu chuẩn, HTTP DELETE phải chứa no body . Bạn có thể sử dụng tùy chọn jqGrid formDeleting
để chỉ định tất cả các tùy chọn Xóa và bạn có thể xác định url
tham số dưới dạng hàm:
formDeleting: {
mtype: "DELETE",
url: function (rowid) {
return "/RestWithDatabaseConnection/rest/delete/" + rowid;
},
ajaxDelOptions: { contentType: "application/json" },
serializeDelData: function () {
return "";
}
}
Nguyên nhân bạn cần sửa đổi mã máy chủ của mình là /RestWithDatabaseConnection/rest/delete/
để sử dụng cùng một giao thức truyền thông và lấy id bị xóa khỏi URL.
Bạn có thể sử dụng navOptions
tham số của jqGrid miễn phí để chỉ định các tùy chọn của navGrid
:
navOptions: { edit: false, add: false }
(searchtext: 'Search'
và các tùy chọn khác mà bạn sử dụng dường như có giá trị mặc định và tôi đã xóa ở đó).
Để gần với tiêu chuẩn REST, người ta có thể sử dụng thao tác HTTP PUT để chỉnh sửa hàng và HTTP POST để thêm hàng mới. Bạn nên triển khai khác nhau điểm vào cho cả hai hoạt động trên chương trình phụ trợ. Bạn sử dụng /RestWithDatabaseConnection/rest/update
rồi và bạn có thể triển khai /RestWithDatabaseConnection/rest/create
để thêm hàng mới. Bạn có thể sử dụng inlineEditing
sau thay đổi ví dụ để thực hiện kịch bản:
inlineNavOptions: { add: true, edit: true },
inlineEditing: {
url: function (id, editOrAdd) {
return "/RestWithDatabaseConnection/rest/" +
(editOrAdd === "edit" ? "update" : "create");
},
mtype: function (editOrAdd) {
return editOrAdd === "edit" ? "PUT" : "POST";
},
keys: true,
serializeSaveData: function (postData) {
return JSON.stringify(dataToSend);
},
aftersavefunc: function () {
$(this).trigger("reloadGrid", [{current: true, fromServer: true}]);
},
addParams: {
addRowParams: {
position: "last",
serializeSaveData: function (postData) {
var dataToSend = $.extend({}, postData);
// don't send any id in case of creating new row
// or to send `0`:
delete dataToSend.id; // or dataToSend.id = 0;
return JSON.stringify(dataToSend);
}
}
}
}