【问题标题】:Kendo Observable remote datasource update is not being called未调用 Kendo Observable 远程数据源更新
【发布时间】:2020-12-04 22:00:29
【问题描述】:

我有一个 HTML 有界表单,我从 Kendo Observable 数据源读取按钮加载数据,但如果用户更新表单,然后单击更新按钮,ViewModel 会更新,但数据源永远不会更新以发送新数据返回服务器。

我正在使用类似于这篇文章的模型、数据源对象和可观察对象: Kendo MVVM create new record with remote datasource

关于如何获取数据源传输:要调用更新以同步到远程服务器的任何想法?

我的更新是通过单击 observable 中的 vsaveupdt 按钮完成的,如下所示

表单模型

 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} }                                
                            }
                        });

远程数据源

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,                                                                                                                   
});                  

可观察

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();                                    
              }
     },...  

【问题讨论】:

  • 一旦 observable 准备好调用更新传输方法,您需要调用数据源的同步方法。文档:docs.telerik.com/kendo-ui/api/javascript/data/datasource/…
  • 我不熟悉 vsaveupdt,但是如果你想处理一个按钮的点击事件然后设置点击绑定:docs.telerik.com/kendo-ui/framework/mvvm/bindings/click
  • 同步将保存所有数据项更改。因此,如果 observable 已更新,它将被传递到更新传输,而您必须手动传递任何内容。
  • 所以我可以看到 observable 更新了模型,但是 datasource.sync 没有做任何事情来触发更新传输.. 其他传输方法的工作方式类似于读取.. 但不是更新
  • 如果你使用get方法(docs.telerik.com/kendo-ui/api/javascript/data/datasource/…)从数据源获取observable,更新observable的值,然后调用sync,那么它应该调用了更新传输方法。跨度>

标签: mvvm kendo-ui observable datasource


【解决方案1】:

您需要使用 Get 方法从数据源获取 observable:https://docs.telerik.com/kendo-ui/api/javascript/data/datasource/methods/get

使用 Set 方法设置 observable 的值: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>

【讨论】:

  • 这是如何工作的,因为我使用的是绑定到可观察对象(表单)的 HTML 表单。我的远程数据源(formSource)本身就是一个对象,而我的 observable 有数据(表单),它是定义的模型的一个实例?我没有看到您使用了 observable,并且我的模型是在远程数据源 (formSource) 的初始化之外定义的。
  • 你可以打电话给kendo.bind($("#my-form"), viewmodel);而不是form.setOptions({ formData: viewmodel });
  • 我想我的主要问题是,我已经有了带有 kendo.bind 的 viewModel,但我需要在我的 vsaveupdt(单击有界事件)函数中进行更新,但我已经用 get 尝试了你的上述操作并为数据源数据设置事件,但数据源数据声明未定义(不确定是否是因为我的数据源是一个对象)......我能够使用插入方法更新数据源数据,但随后使用同步方法不执行更新传输,而是执行创建函数。
  • 如果你能......你能不能用一个 HTML 表单来更新你的例子,以显示上面的例子而不是 Kendoform 小部件
  • 如何使用远程数据源完成此操作?基本上,在我使用按钮运行读取传输后,单击以加载表单值,编辑,然后单击更新按钮......(请记住,有界表单模型,可观察的实例,看起来被更新但不是数据源)......即使我在提交功能上使用数据源更新仍然没有被调用,并且我可以看到它在给定控制台日志的事件中,但是数据源同步的行为就像它没有数据/未定义所以什么都没有发生。
【解决方案2】:

datasource insert... 方法看起来与 sync 方法一起工作,以将数据发送到远程服务,因为它现在正在调用传输更新。请参阅下面的更新上下文

$(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();
 });
...

【讨论】:

    猜你喜欢
    • 2014-09-08
    • 1970-01-01
    • 2021-01-26
    • 1970-01-01
    • 1970-01-01
    • 2022-08-03
    • 1970-01-01
    • 2014-03-18
    • 1970-01-01
    相关资源
    最近更新 更多