Knockout Js: ko.mapping.from JS и binding => как это сделать правильно? - PullRequest
0 голосов
/ 25 апреля 2020

Я действительно борюсь с чем-то, что мне показалось простым ...

Я делаю простую таблицу результатов поиска на основе вызова $ .get JSON и хочу сохранить свой код как " generi c "насколько возможно.

По моему (упрощенно) HTML:

<form id="searchForm">
(...)
    <button type="button" onclick="search()">Search</button>
</form>

(...)
<tbody data-bind="foreach: data">
    <tr>
        <td data-bind="text: FOO"></td>
(...)
        <td data-bind="text: BAR"></td>
    </tr>
</tbody>

Затем по моим javascript (в script тегах ниже на странице):

var search = function(){
    var form = $('#searchForm');
    $.getJSON("php/query/jsonQuery.php?jsonQuery=search", form.serialize(), function(jsonAnswer, textStatus) {
        console.log(jsonAnswer);
        if(typeof viewModel === 'undefined'){
            var viewModel = ko.mapping.fromJS(jsonAnswer);
            ko.applyBindings(viewModel);
        }
        else{
            ko.mapping.fromJS(jsonAnswer, viewModel);
        }
        $('#divResults').show();
//         console.log(viewModel)
    });
}

Это прекрасно работает при первом щелчке "поиск" ... но не при следующем: Error You cannot apply bindings multiple times to the same element.

Как вы можете догадаться, это очень уродливое "if" тестирование viewModel это отчаянная попытка избавиться от этой ошибки.

Я пробовал много вещей, но я просто не могу понять, как это сделать правильно ...

Я читал это Knockout JS обновить представление из json модель и этот Knockout Js v2.3.0: Ошибка Невозможно несколько раз применить привязки к одному и тому же элементу , но это не помогло мне очень ... может быть, потому что функция search () не вызывается при загрузке (и действительно не должна быть).

Любой мастер KO, чтобы дать мне подсказку? Заранее спасибо за помощь!

1 Ответ

1 голос
/ 27 апреля 2020

Вот как бы я приблизился к тому, что вы пытаетесь выполнить sh.

var searchService = {
  search: function(form, vmData) {
    //$.getJSON("php/query/jsonQuery.php?jsonQuery=search", form.serialize(), function(jsonAnswer, textStatus) {
      var jsonAnswer = [{
        FOO: "Item 1 Foo",
        BAR: "Item 1 Bar"
      }, {
        FOO: "Item 2 Foo",
        BAR: "Item 2 Bar"
      }]
      ko.mapping.fromJS(jsonAnswer, [], vmData);
      //})
    }
};

var PageViewModel = function() {
  var self = this;
  self.data = ko.observableArray();
  self.hasResults = ko.pureComputed(function() {
    return self.data().length > 0;
  });

  self.search = function() {
    var form = $('#searchForm');
    searchService.search(form, self.data);
  };
};

ko.applyBindings(new PageViewModel());
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.4.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script>

<form id="searchForm">
  <button type="button" data-bind="click:search">Search</button>
</form>
<div data-bind="visible: !hasResults()"><b>No Results</b></div>
<div data-bind="visible: hasResults">
  <table class="table">
    <thead>
      <tr>
        <td>FOO</td>
        <td>BAR</td>
      </tr>
    </thead>
    <tbody data-bind="foreach: data">
      <tr>
        <td data-bind="text: FOO"></td>
        <td data-bind="text: BAR"></td>
      </tr>
    </tbody>
  </table>
</div>
<br/>
<pre><code data-bind="text: ko.toJSON($root)">
...