Knockout - два наблюдаемых поля обновляют друг друга - PullRequest
1 голос
/ 07 февраля 2020

У меня есть два поля в форме; «Дни» и «Дата».

<div id="myForm">
    <label for="days">Days</label>
    <input id="days" type="text" data-bind="value:myViewModel.days" />

    <label for="date">Date</label>
    <input id="date" type="text" data-bind="value:myViewModel.date" />
</div>

Каждое поле привязано к наблюдаемой КО. Я хотел бы, чтобы пользователь мог редактировать любое из этих полей, а другое поле автоматически обновляться.

Моя ViewModel выглядит следующим образом (упрощено, чтобы сохранить краткость):

myViewModel = new function () {
    var self = this;
    self.days = ko.observable(10);
    self.date = ko.observable('2020-02-06');
};

myViewModel.days.subscribe(function (newValue) {
    var newDate = JSON call to get new date using newValue
    myViewModel.date(newDate);
});

myViewModel.date.subscribe(function (newValue) {
    var newDays = JSON call to get days using newValue
    myViewModel.days(newDays);
});

У меня проблема в том, что оба значения являются наблюдаемыми, и каждое обновляет другое, как только одно из значений автоматически обновляется, оно запускает еще l oop обновлений. Есть ли альтернативный подход, чтобы получить желаемое поведение?

Большое спасибо заранее.

1 Ответ

1 голос
/ 07 февраля 2020

Один из способов сделать это - привязать пользовательский интерфейс к вычисляемому для записи, а не к наблюдаемым напрямую. Обновления пользовательского интерфейса отправляются вычисляемому, и вычисляемый определяет, какие базовые наблюдаемые обновляются без запуска каких-либо дальнейших (модельных) обновлений.

function viewModel(){
  var self = this;
  
  this._observable1 = ko.observable(10);
  this._observable2 = ko.observable(20);
  
  this.observable1 = ko.computed({
    read: function(val){
      return self._observable1();
    },
    write: function(val){
      self._observable1(val);
      self._observable2(val*2); //also update 2
      console.log('1 updated');    
    }
  });
  
  this.observable2 = ko.computed({
    read: function(val){
      return self._observable2();
    },
    write: function(val){
      self._observable2(val);
      self._observable1(val / 2); //also update 1
      console.log('2 updated');    
    }
  });
}

ko.applyBindings(new viewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

1: <input type="text" data-bind="textInput: observable1"/>
<br/>
2: <input type="text" data-bind="textInput: observable2"/>
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...