ASP.NET MVC Knockout 按钮单击调用 POST API

问题描述

我的前端有一个 html 表格(列表),对于每一行,我有一个按钮:

...
<td>
  <button data-bind="click: sendDataToApi">Test button</button>
</td>
...

在 .js 文件我有这样的东西:

define(['viewmodels/shell','durandal/services/logger','plugins/dialog','viewmodels/shell','toastr','knockout','kovalidationconfig','plugins/router','typeahead.bundle'],function (shell,logger,dialog,shell,toastr,ko,kvc,router,typeahead) {
        var vm = {
            activate: activate,shell: shell,data: ko.observableArray([]),close: function () {
                $(window).off('popstate',vm.goBack);
                $(window).off('resize',adjustModalPosition);
                dialog.close(vm,'cancel');
            },goBack: function () {
                $(window).off('popstate','back');
            },editPreregisteredChildren: function () {
                router.navigate("#/function/" + this.id);
            },currentPage: ko.observable(1),itemsPerPage: ko.observable(10),hasNextPage: ko.observable(false),prevIoUsPage: prevIoUsPage,nextPage: nextPage,sendDataToApi: function () {console.log("sdsdsds")},searchCriteria: ko.observable(''),applySearch: applySearch,locations: ko.observableArray([]),locationId: ko.observable(),LocationName: ko.observable(),exportHref: ko.observable("/spa/ExportSchedulings"),bindingComplete: function (view) {
                bindFindLocationEvent(view);
            }
        };

        function sendDataToApi() {
            console.log("hello.")
        };

    });

所以,首先,我想让 console.log("something") 工作。

现在我在我的 chrome 控制台中遇到错误

Uncaught ReferenceError: Unable to process binding "click: function(){return sendDataToApi }"
Message: sendDataToApi is not defined

我不明白为什么?

之后我需要对我的控制器进行ajax调用,并在该控制器中调用一些api,如果api调用成功与否返回信息。

解决方法

我将假设您尝试在给定的表格中显示信息

<td>
  <button data-bind="click: sendDataToApi">Test button</button>
</td>

我还将假设在表或表体级别存在 ko:foreach。如果是这种情况,则 sendDataToApi 与父 vm 对象相关联,而不是当前用于创建表行的对象。

如果是这种情况,则您需要使用 $parent.sendDataToApi$root.sendDataToApi

<td>
  <button data-bind="click: $parent.sendDataToApi">Test button</button>
</td>

<td>
  <button data-bind="click: $root.sendDataToApi">Test button</button>
</td>

编辑

你只需要在接收函数中添加一个参数,因为knockout传递的是当前对象。

var serverData = [{
    id: 1,name: 'Test 1'
  },{
    id: 2,name: 'Test 2'
  },{
    id: 3,name: 'Test 3'
  },];

function ViewModel() {
  var self = this;
  self.data = ko.observableArray([]);

  self.checkServer = function checkServer(row) {
    console.log(ko.toJS(row));
  }


  self.fillTable = function fillTable() {
    var mappedData = serverData.map(r => new RowViewModel(r));
    self.data(mappedData);
  }


  
}

function RowViewModel(data) {
  var self = this;
  self.id = ko.observable(data.id || 0);
  self.name = ko.observable(data.name || '');


}
ko.applyBindings(new ViewModel());
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.6.0/css/bootstrap.min.css" rel="stylesheet"/>

<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<button class="button" data-bind="click: fillTable">Fill Table</button>
<table class="table">

  <tbody data-bind="foreach: data">
    <tr>
      <td data-bind="text: id"></td>
      <td data-bind="text: name"></td>
      <td>
        <button data-bind="click: $parent.checkServer">Check Server</button>
      </td>
    </tr>
  </tbody>
</table>