【问题标题】:Prevent knockout from calling subscribe when the observable is set设置 observable 时防止敲除调用 subscribe
【发布时间】:2018-01-12 06:58:15
【问题描述】:

我有两个绑定到它们自己的 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

【问题讨论】:

    标签: javascript jquery ajax knockout.js


    【解决方案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 可观察对象,在其 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" />

    【讨论】:

    • 可写的计算函数正是我想要的。这帮助我解决了我的问题:)
    【解决方案2】:

    在调用 ajax 请求之前,您总是可以检查卡号或公司名称是否已经存在。

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

    【讨论】:

      猜你喜欢
      • 2017-11-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-04-08
      相关资源
      最近更新 更多