Kendo 未调用可观察的远程数据源更新
Kendo Observable remote datasource update is not being called
我有一个 HTML 有界表单,我从 Kendo Observable 数据源读取按钮加载数据,但是如果用户更新表单,然后单击更新按钮,ViewModel 会更新但是数据源永远不会更新以将新数据发送回服务器。
我正在使用与此类似的模型、数据源对象和可观察对象 post:
Kendo MVVM create new record with remote datasource
关于如何调用数据源 transport:update 以同步到远程服务器有什么想法吗?
我的更新是通过在 observable 中单击 vsaveupdt 按钮完成的,如下所示
Form Model
var formModel = kendo.data.Model.define({
id: "investigation_id",
fields: {
investigation_id: { hidden: true, type: 'number' },
sr_number: { type: 'number', editable: true, defaultValue: null, validation: { required: { message: "SR Number cannot be empty" } } },
ticket_number: { type: 'string', validation: { required: false} },
updt_datetime: { type: 'date', validation: { required: false} },
script_name: { type: 'string', editable: true, validation: { required: { message: "SR Number cannot be empty" } } },
script_name_chg_ind: { type: 'number', validation: { required: false} },
standard_ind: { type: 'number', editable: true, validation: { required: false} },
change_type: { type: 'number', editable: true, validation: { required: { message: "Change Type needs selection" } } },
change_type_details: { type: 'string', editable: true, validation: { required: false} },
resolution_type: { type: 'number', editable: true, validation: { required: false} },
resolution_type_details: { type: 'string', editable: true, validation: { required: false} },
resolution_subtype: { type: 'number', editable: true, validation: { required: false} },
description: { type: 'string', editable: true, validation: { required: { message: "Description cannot be empty" } } },
tech_details: { type: 'string', editable: true, validation: { required: { message: "Technical Details cannot be empty" } } },
inv_details: { type: 'string', editable: true,validation: { required: { message: "Investigation Details cannot be empty" } } },
possible_change: { type: 'string', editable: true, validation: { required: false} },
filename: { type: 'string', validation: { required: { message: "Filename cannot be empty" } } },
filepath: { type: 'string', validation: { required: { message: "Filepath cannot be empty" } } },
test_files: { type: 'string', validation: { required: false} },
work_effort: { type: 'string', editable: true, validation: { required: false} }
}
});
Remote DataSource
var formSource = new kendo.data.DataSource({
transport: {
read: function(){
const sr_number = $('#sr_number');
$.ajax({
url: "triage_inv/form",
dataType: "json",
type: 'GET',
data: { srNumber : sr_number.val() },
complete: function(response) {
var res = response.responseJSON;
console.log('read reply',res);
console.log('datasource length =',res.length);
...
}
});
},
create: function(options){
$.ajax({
url: "triage_inv/form/create",
dataType: "json",
data: { models: kendo.stringify(options.data.models) },
complete: function() {
toastr.info('success', 'INV Doc created!');
$('button#save').text('Update');
}
});
},
update: function(options){
const sr_number = $('#sr_number');
$.ajax({
url: "triage_inv/form/update",
dataType: "json",
data:{srNumber :sr_number.val(),models:kendo.stringify(options.data.models)
},
complete: function() {
toastr.info('success', 'INV Doc updated!');
$('button#save').text('Update');
}
});
},
sort: { field: "open_dt_tm", dir: "asc"}
},
batch: true,
schema: {
model: formModel
},
pageSize: 20,
page: 1,
});
Observable
var form = kendo.observable({
forms: new formModel(),
standard_ind: 0, change_type: 0,
resolution_type: 0,resolution_subtype: 0,
getstd: function(){ return this.get("forms.standard_ind"); },
getchg: function(){ return this.get("forms.change_type"); },
getrestype: function(){ return this.get("forms.resolution_type"); },
getresstype: function(){ return this.get("forms.resolution_subtype"); },
vsaveupdt: function(e){
remoteDataSource.fetch(function(){
var data = this.data();
console.log('grid data > ',data);
const sr_number = $('#sr_number').val();
if(sr_number == form.sr_number){
$('#tckt_no').text(data.ticket_number);
}
});
var njson = this.forms;
console.log("object->",njson);
var btntext = $('button#save').text();
console.log(btntext);
var std = this.getstd();
var chg = this.getchg();
console.log('save/update chg >',chg) ;
var restype = this.getrestype();
var resstype = this.getresstype();
var ticketnum = $('#tckt_no').text();
njson.set("standard_ind",std);
njson.set("change_type",chg);
njson.set("resolution_type",restype);
njson.set("resolution_subtype",resstype);
njson.set("ticket_number",ticketnum);
if( btntext == 'Update'){
console.log('data change ',njson);
form.set("forms",njson);
formSource.sync();
}else{
console.log('Save change ',njson);
formSource.add(njson);
formSource.sync();
}
},...
您需要使用 Get 方法从数据源获取可观察对象:https://docs.telerik.com/kendo-ui/api/javascript/data/datasource/methods/get
设置可观察值的值是使用 Set 方法设置的:https://docs.telerik.com/kendo-ui/api/javascript/data/model/methods/set
设置值后,调用 Sync 方法:https://docs.telerik.com/kendo-ui/api/javascript/data/datasource/methods/sync
这是一个使用 Kendo 的表单小部件的示例
var dataSource = new kendo.data.DataSource({
transport: {
read: function(options) {
// this is just for demo, you'd have your actuall transport setup
options.success([
{ Id: 1, FirstName: "Jane", LastName: "Doe", age: 30 },
{ Id: 2, FirstName: "John", LastName: "Doe", age: 33 }
]);
},
update: function(options) {
console.log(options);
}
},
schema: {
model: { id: "Id" }
}
});
$(document).ready(function () {
$("#edit-form").kendoForm({
orientation: "vertical",
formData: {},
items: [{
type: "group",
label: "Edit Form",
items: [
{ field: "FirstName", label: "First Name", validation: { required: true } },
{ field: "LastName", label: "Last Name", validation: { required: true } },
{ field: "Age", label: { text: "Age", optional: true }, editor: "NumericTextBox", editorOptions: { format: "N0"} }
]
}],
submit: function(e) {
e.preventDefault();
var viewmodel = dataSource.get(1);
viewmodel.set("FirstName", e.model.FirstName);
viewmodel.set("LastName", e.model.LastName);
viewmodel.set("Age", e.model.Age);
dataSource.sync();
}
});
var form = $("#edit-form").getKendoForm();
dataSource.fetch(function() {
var viewmodel = dataSource.get(1);
form.setOptions({ formData: viewmodel });
});
});
<link href="https://kendo.cdn.telerik.com/2020.3.1118/styles/kendo.material-v2.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="edit-form"></form>
<script src="https://kendo.cdn.telerik.com/2020.3.1118/js/kendo.all.min.js"></script>
道场:Live Demo
更新
根据 OP 的要求,如果没有 kendo-ui 形式,这是如何完成的:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled</title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2020.3.1118/styles/kendo.material-v2.min.css">
<body>
<form id="edit-form">
<input type="text" class="k-textbox" placeholder="First Name" data-bind="value: FirstName" />
<input type="text" class="k-textbox" placeholder="Last Name" data-bind="value: LastName" />
<input type="number" class="k-textbox" placeholder="Age"
data-role="numerictextbox"
data-format="N0"
data-min="0"
data-bind="value: Age">
<button type="submit">Submit</button>
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2020.3.1118/js/kendo.all.min.js"></script>
<script>
var dataSource = new kendo.data.DataSource({
transport: {
read: function(options) {
// this is just for demo, you'd have your actuall transport setup
options.success([
{ Id: 1, FirstName: "Jane", LastName: "Doe", Age: 30 },
{ Id: 2, FirstName: "John", LastName: "Doe", Age: 33 }
]);
},
update: function(options) {
console.log(options);
}
},
schema: {
model: { id: "Id" }
}
});
$(document).ready(function () {
var form = $("#edit-form");
dataSource.fetch(function() {
var viewmodel = dataSource.get(1);
kendo.bind(form, viewmodel);
});
$("#edit-form").on("submit", function(e) {
e.preventDefault();
dataSource.sync();
});
});
</script>
</body>
</html>
数据源插入...方法看起来已经与同步方法一起工作以将数据发送到远程服务,因为它现在正在调用传输更新。请参阅下面更新的上下文
$(document).ready(function () {
...
$("#triage_form").on("submit", function(e){
var uson = form.forms;
uson.set('id',1);
console.log('data change ',form.forms);
formSource.insert(0,uson);
e.preventDefault();
formSource.sync();
});
...
我有一个 HTML 有界表单,我从 Kendo Observable 数据源读取按钮加载数据,但是如果用户更新表单,然后单击更新按钮,ViewModel 会更新但是数据源永远不会更新以将新数据发送回服务器。
我正在使用与此类似的模型、数据源对象和可观察对象 post: Kendo MVVM create new record with remote datasource
关于如何调用数据源 transport:update 以同步到远程服务器有什么想法吗?
我的更新是通过在 observable 中单击 vsaveupdt 按钮完成的,如下所示
Form Model
var formModel = kendo.data.Model.define({
id: "investigation_id",
fields: {
investigation_id: { hidden: true, type: 'number' },
sr_number: { type: 'number', editable: true, defaultValue: null, validation: { required: { message: "SR Number cannot be empty" } } },
ticket_number: { type: 'string', validation: { required: false} },
updt_datetime: { type: 'date', validation: { required: false} },
script_name: { type: 'string', editable: true, validation: { required: { message: "SR Number cannot be empty" } } },
script_name_chg_ind: { type: 'number', validation: { required: false} },
standard_ind: { type: 'number', editable: true, validation: { required: false} },
change_type: { type: 'number', editable: true, validation: { required: { message: "Change Type needs selection" } } },
change_type_details: { type: 'string', editable: true, validation: { required: false} },
resolution_type: { type: 'number', editable: true, validation: { required: false} },
resolution_type_details: { type: 'string', editable: true, validation: { required: false} },
resolution_subtype: { type: 'number', editable: true, validation: { required: false} },
description: { type: 'string', editable: true, validation: { required: { message: "Description cannot be empty" } } },
tech_details: { type: 'string', editable: true, validation: { required: { message: "Technical Details cannot be empty" } } },
inv_details: { type: 'string', editable: true,validation: { required: { message: "Investigation Details cannot be empty" } } },
possible_change: { type: 'string', editable: true, validation: { required: false} },
filename: { type: 'string', validation: { required: { message: "Filename cannot be empty" } } },
filepath: { type: 'string', validation: { required: { message: "Filepath cannot be empty" } } },
test_files: { type: 'string', validation: { required: false} },
work_effort: { type: 'string', editable: true, validation: { required: false} }
}
});
Remote DataSource
var formSource = new kendo.data.DataSource({
transport: {
read: function(){
const sr_number = $('#sr_number');
$.ajax({
url: "triage_inv/form",
dataType: "json",
type: 'GET',
data: { srNumber : sr_number.val() },
complete: function(response) {
var res = response.responseJSON;
console.log('read reply',res);
console.log('datasource length =',res.length);
...
}
});
},
create: function(options){
$.ajax({
url: "triage_inv/form/create",
dataType: "json",
data: { models: kendo.stringify(options.data.models) },
complete: function() {
toastr.info('success', 'INV Doc created!');
$('button#save').text('Update');
}
});
},
update: function(options){
const sr_number = $('#sr_number');
$.ajax({
url: "triage_inv/form/update",
dataType: "json",
data:{srNumber :sr_number.val(),models:kendo.stringify(options.data.models)
},
complete: function() {
toastr.info('success', 'INV Doc updated!');
$('button#save').text('Update');
}
});
},
sort: { field: "open_dt_tm", dir: "asc"}
},
batch: true,
schema: {
model: formModel
},
pageSize: 20,
page: 1,
});
Observable
var form = kendo.observable({
forms: new formModel(),
standard_ind: 0, change_type: 0,
resolution_type: 0,resolution_subtype: 0,
getstd: function(){ return this.get("forms.standard_ind"); },
getchg: function(){ return this.get("forms.change_type"); },
getrestype: function(){ return this.get("forms.resolution_type"); },
getresstype: function(){ return this.get("forms.resolution_subtype"); },
vsaveupdt: function(e){
remoteDataSource.fetch(function(){
var data = this.data();
console.log('grid data > ',data);
const sr_number = $('#sr_number').val();
if(sr_number == form.sr_number){
$('#tckt_no').text(data.ticket_number);
}
});
var njson = this.forms;
console.log("object->",njson);
var btntext = $('button#save').text();
console.log(btntext);
var std = this.getstd();
var chg = this.getchg();
console.log('save/update chg >',chg) ;
var restype = this.getrestype();
var resstype = this.getresstype();
var ticketnum = $('#tckt_no').text();
njson.set("standard_ind",std);
njson.set("change_type",chg);
njson.set("resolution_type",restype);
njson.set("resolution_subtype",resstype);
njson.set("ticket_number",ticketnum);
if( btntext == 'Update'){
console.log('data change ',njson);
form.set("forms",njson);
formSource.sync();
}else{
console.log('Save change ',njson);
formSource.add(njson);
formSource.sync();
}
},...
您需要使用 Get 方法从数据源获取可观察对象:https://docs.telerik.com/kendo-ui/api/javascript/data/datasource/methods/get
设置可观察值的值是使用 Set 方法设置的:https://docs.telerik.com/kendo-ui/api/javascript/data/model/methods/set
设置值后,调用 Sync 方法:https://docs.telerik.com/kendo-ui/api/javascript/data/datasource/methods/sync
这是一个使用 Kendo 的表单小部件的示例
var dataSource = new kendo.data.DataSource({
transport: {
read: function(options) {
// this is just for demo, you'd have your actuall transport setup
options.success([
{ Id: 1, FirstName: "Jane", LastName: "Doe", age: 30 },
{ Id: 2, FirstName: "John", LastName: "Doe", age: 33 }
]);
},
update: function(options) {
console.log(options);
}
},
schema: {
model: { id: "Id" }
}
});
$(document).ready(function () {
$("#edit-form").kendoForm({
orientation: "vertical",
formData: {},
items: [{
type: "group",
label: "Edit Form",
items: [
{ field: "FirstName", label: "First Name", validation: { required: true } },
{ field: "LastName", label: "Last Name", validation: { required: true } },
{ field: "Age", label: { text: "Age", optional: true }, editor: "NumericTextBox", editorOptions: { format: "N0"} }
]
}],
submit: function(e) {
e.preventDefault();
var viewmodel = dataSource.get(1);
viewmodel.set("FirstName", e.model.FirstName);
viewmodel.set("LastName", e.model.LastName);
viewmodel.set("Age", e.model.Age);
dataSource.sync();
}
});
var form = $("#edit-form").getKendoForm();
dataSource.fetch(function() {
var viewmodel = dataSource.get(1);
form.setOptions({ formData: viewmodel });
});
});
<link href="https://kendo.cdn.telerik.com/2020.3.1118/styles/kendo.material-v2.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<form id="edit-form"></form>
<script src="https://kendo.cdn.telerik.com/2020.3.1118/js/kendo.all.min.js"></script>
道场:Live Demo
更新
根据 OP 的要求,如果没有 kendo-ui 形式,这是如何完成的:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Untitled</title>
<link rel="stylesheet" href="https://kendo.cdn.telerik.com/2020.3.1118/styles/kendo.material-v2.min.css">
<body>
<form id="edit-form">
<input type="text" class="k-textbox" placeholder="First Name" data-bind="value: FirstName" />
<input type="text" class="k-textbox" placeholder="Last Name" data-bind="value: LastName" />
<input type="number" class="k-textbox" placeholder="Age"
data-role="numerictextbox"
data-format="N0"
data-min="0"
data-bind="value: Age">
<button type="submit">Submit</button>
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://kendo.cdn.telerik.com/2020.3.1118/js/kendo.all.min.js"></script>
<script>
var dataSource = new kendo.data.DataSource({
transport: {
read: function(options) {
// this is just for demo, you'd have your actuall transport setup
options.success([
{ Id: 1, FirstName: "Jane", LastName: "Doe", Age: 30 },
{ Id: 2, FirstName: "John", LastName: "Doe", Age: 33 }
]);
},
update: function(options) {
console.log(options);
}
},
schema: {
model: { id: "Id" }
}
});
$(document).ready(function () {
var form = $("#edit-form");
dataSource.fetch(function() {
var viewmodel = dataSource.get(1);
kendo.bind(form, viewmodel);
});
$("#edit-form").on("submit", function(e) {
e.preventDefault();
dataSource.sync();
});
});
</script>
</body>
</html>
数据源插入...方法看起来已经与同步方法一起工作以将数据发送到远程服务,因为它现在正在调用传输更新。请参阅下面更新的上下文
$(document).ready(function () {
...
$("#triage_form").on("submit", function(e){
var uson = form.forms;
uson.set('id',1);
console.log('data change ',form.forms);
formSource.insert(0,uson);
e.preventDefault();
formSource.sync();
});
...