Knockoutjs订阅事件,ko.computed执行计时问题

时间:2014-09-16 19:58:47

标签: javascript knockout.js

当self.selectedQueryId更改时,我想在knockoutjs中为self.selectedTitleId()设置不同的值,所以我添加了对selectedQueryId的订阅。 我有另一个计算变量self.text,它将self.selectedTitleId与其他变量格式化。

我的问题是,当我从UI更改selectedQueryId值时,首先调用计算函数,然后调用subscribe调用。因此,我尝试显示的文本始终保留以前的选择值。

我想保持self.text计算函数执行,直到selectedTitleId.subscribe函数完成,以便self.selectedTitleId具有当前值。

有人能帮助我吗?谢谢你的时间!

下面是html组件,用于通过UI绑定selectedTitleId值。后端js总是显示' backendName'作为值,即使我尝试使用self.selectedTitleId(" newValue")设置不同的值。          HTML:           

      var sformat = (function() {
       var pattern = /\{\{|\}\}|\{(\d+)\}/g;
         return function () {
         var parameters = arguments;
         if(parameters[0]) {
           console.log(parameters[0])
           return parameters[0].replace(pattern, function (match, group) {
             var value;
              if (match === "{{")
                return "{";
              if (match === "}}")
                return "}";
             value = parameters[parseInt(group, 10) + 1];
             return value ? value.toString() : "";
            });
         }
       };
     });

       function test() {
         return sformat.apply(this, arguments);
       }

       self.selectedTitleId = ko.observable('');

       self.text = ko.computed(function () {
        console.log("inside text function")

        if (self.selectedTitleId && self.selectedQueryId()) {
          console.log(self.selectedTitleId)
          self.displayField = test(self.selectedTitleId, self.selectedQueryId(),self.queryValue());
        }else if(self.selectedTitleId && self.selectedQueryId() && self.queryGreaterValue() &&   self.queryLesserValue()){
          self.displayField = test(self.selectedTitleId, self.selectedQueryId(),self.queryValue(),self.queryGreaterValue(),self.queryLesserValue());
        }
     return self.displayField;
    });

    self.selectedQueryId.subscribe(function (newValue) {

        $.getJSON("json/queries.json", function (allData) {
            var mappedData = $.map(allData, function (item) {
                if(item.DisplayName == "Price"){
                    if(newValue == "range") {
                        self.selectedTitleId(item.RangeBackEndFieldName);
                        console.log("range");
                        console.log(item.RangeBackEndFieldName); //Prints new string
                        console.log(self.selectedTitleId()); //Print old value- 
                    }else if(newValue == "$gt:" || newValue == "$lt:"){
                        self.selectedTitleId(item.BackendFieldName);
                        });
                    }
                }
            });
        });
});

1 个答案:

答案 0 :(得分:0)

除非您没有告诉我们其他内容,否则selectedTitleId成为ko.computed是没有意义的。只需使用常规的observable:

self.selectedTitleId = ko.observable();

self.selectedQueryId.subscribe(function (newValue) {

    $.getJSON("json/queries.json", function (allData) {
        var mappedData = $.map(allData, function (item) {
            if(item.DisplayName == "Price"){
                if(newValue == "range") {
                    self.selectedTitleId(item.RangeBackEndFieldName);
                    });
                }else if(newValue == "$gt:" || newValue == "$lt:"){
                    self.selectedTitleId(item.BackendFieldName);
                    });
                }
            }
        });
    });
});

现在,当您的回调中更改了selectedTitleId时,它应该触发text重新评估。

原始问题并非首先更新text,而是在您更改selectedTitleId时没有重新评估。见这里:

if (self.selectedTitleId() && self.selectedQueryId()) {

这意味着您的computed属性同时依赖selectedTitleIdselectedQueryId,更新任何一项都会导致该函数再次运行。但是在您的原始代码中,您完全用全新的函数替换了self.selectedTitleId,但您的computed仍然依赖于旧版本(未更改)。