如何忽略用户未完成的更改?

时间:2017-10-26 13:45:59

标签: javascript knockout.js observable

我的viewmodel中有一个ko.observable,它附加到一个输入。当用户更改该输入的值(每个字符)时,我运行AJAX调用,从后端下载建议。

当用户选择其中一个建议时,我希望用所选值填充输入,但不发送AJAX调用。但设置可观察的值仍然会触发附加到textInput绑定的事件和调用函数。

如何在不触发textInput的情况下设置可观察的值?

示例代码:

var name = ko.observable();
name.subscribe(nameChanged);

var nameChanged = function() {
    someService.post(name(), success, failure);
}

var someAction = function() {

    name("Test"); // I don't want to trigger AJAX call here
}
<input type="text" data-bind="textInput: name" />

4 个答案:

答案 0 :(得分:1)

另一个选择是使用计算的observable作为中介。 ajax函数可以在计算的write事件中触发,以便直接写入observable绕过它。

function viewModel(){
    var self = this;
    
    self.realName = ko.observable('test');
    
    self.Name = ko.computed({
        read: function(){
            return self.realName();
        },
        write: function(value){
            self.realName(value);
            nameChanged(value);
        }
    });
    
    function nameChanged(newName) {
        console.log("name changed:", newName);
    }
    
    self.modifyName = function(){
        self.realName(self.realName() + 'z');
    }
}

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


<input type="text" data-bind="textInput: Name" />
<br />
<button data-bind="click: modifyName">Modify</button>

答案 1 :(得分:0)

在选择完成后,可能在字段上设置一个特定的CSS类,并在ajax调用周围添加一些逻辑来检查字段是否具有CSS类。

答案 2 :(得分:0)

您可以将ajax调用绑定到ui元素的change事件,而不是订阅observable的change事件。您将摆脱name.subscribe(nameChanged);并添加event绑定:

data-bind="textInput: name, event: { changed: nameChanged }"

答案 3 :(得分:0)

一种“老式”的方式,但不是很优雅,是暂时处理订阅然后重新附加它:

var myName = ko.observable();
var nameSub = myName.subscribe(nameChanged);

function nameChanged(newName) {
    console.log("name changed:", newName);
}

function changeWithoutLog() {
  nameSub.dispose();
  myName("Test");
  nameSub = myName.subscribe(nameChanged);
}


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


<input type="text" data-bind="textInput: name" />
<button data-bind="click: changeWithoutLog">change without post</button>