当设置了observable时,防止knockout调用subscribe

时间:2017-08-04 10:58:46

标签: javascript jquery ajax knockout.js

我有两个输入绑定到他们自己的observable。两者都有一个启动ajax调用的订阅函数。还有一些其他字段将从ajax结果中填写。我希望能够在输入companyName时获取数据。我还希望在键入cardNumber时获取companyName(以及更多),但给companyName一个值将触发其subscibe函数,该函数将启动另一个ajax调用。我想防止这种情况发生。

cardNumber = ko.observable();
companyName = ko.observable();

cardNumber.subscribe(function () {
        getDataFromCardNumber(cardNumber());
});
companyName.subscribe(function () {
        getDataFromCompanyName(companyName());
});

getDataFromCardNumber = function (cardNr) {
    $.ajax({
        type: 'GET',
        data: { number: cardNr },
        url: '/Home/GetCardInfo',
        success: function (data) {
           companyName(data.Company.CompanyName);
           //some other fields
        }
    });
};
//getDataFromCompanyName(name) contains another ajax call to fill out some other fields aswell

2 个答案:

答案 0 :(得分:1)

我看到两个选项:

  • 您可以在从回调写入之前dispose订阅,然后在设置新值时重新附加订阅。

const obsA = ko.observable("a");
const obsB = ko.observable("b");

const updateA = newVal => setTimeout(
  () => {
    subA.dispose();
    obsA("reset by B");
    subA = obsA.subscribe(updateB);
  }, 500);
  
const updateB = newVal => setTimeout(
  () => {
    subB.dispose();
    obsB("reset by A");
    subB = obsB.subscribe(updateA);
  }, 500);


let subA = obsA.subscribe(updateB);
let subB = obsB.subscribe(updateA);

  
ko.applyBindings({ obsA, obsB });
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
A: <input data-bind="value: obsA" />
B: <input data-bind="value: obsB" />

  • 您可以创建单独的UI observable,在其write逻辑中调用更新:

const obsA = ko.observable("a");
const obsB = ko.observable("b");

const uiObsA = ko.computed({
  read: obsA,
  write: val => {
    obsA(val);
    updateB();
  }
});

const uiObsB = ko.computed({
  read: obsB,
  write: val => {
    obsB(val);
    updateA();
  }
});

const updateB = newVal => setTimeout(
  () => obsB("reset by A"), 500);
  
const updateA = newVal => setTimeout(
  () => obsA("reset by B"), 500);
  
ko.applyBindings({ obsA, obsB });
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
A: <input data-bind="value: uiObsA" />
B: <input data-bind="value: uiObsB" />

答案 1 :(得分:1)

You could always just check to see if a card number or company name exists already before you call the ajax request.

cardNumber.subscribe(function () {
    if (!companyName()){
       getDataFromCardNumber(cardNumber());
    }
});

companyName.subscribe(function () {
    if (!cardNumber()){
        getDataFromCompanyName(companyName());
    }
});