Knockout计算在页面加载时执行

时间:2017-04-06 09:26:45

标签: javascript knockout.js

基本上我有一个下拉选择哪个会有另一个下拉加载。我有一个计算变量取决于第一个下拉选择值(我知道它可以订阅,但仍然)。但是计算是在页面加载上执行的,由于内部的AJAX调用,我不想要。 '在页面加载上执行的原因是什么以及如何避免这种情况?

HTML:

<div>
  <select id="selectmenu1" data-bind="options: departments, 
             optionsValue: 'id', 
             optionsText: 'name', 
             optionsCaption: 'Choose...',value: selectedDept">
  </select>
  <select id="selectmenu1" data-bind="options: contacts, 
             optionsValue: 'id', 
             optionsText: 'name', 
             optionsCaption: 'Choose...'">
  </select>
</div>

和JS

// Here's my data model
var ViewModel = function(first, last) {
  var self = this;
  var deptArray = [];
  var deptObj = {
    id: "8888",
    name: "Electrical"
  };
  deptArray[0] = deptObj;
  deptObj = {
    id: "9999",
    name: "Admin"
  };
  deptArray[1] = deptObj;
  self.departments = ko.observableArray(deptArray);
  self.selectedDept = ko.observable();
  self.contacts = ko.observableArray();
  self.contactsRetrieve = ko.computed(function() {
    var deptId = self.selectedDept();
    console.log("entered");
    $.ajax({
      url: '/echo/js',
      complete: function(response) {
        console.log("success");
        var contactArray = [];
        var contactObj = {};
        if (deptId == '8888') {
          contactObj.id = '1234';
          contactObj.name = 'Vivek';
        } else if (deptId == '9999') {
          contactObj.id = '5678';
          contactObj.name = 'Sree';
        }
        contactArray[0] = contactObj;
        self.contacts(contactArray);
      }
    });
    console.log("exited");
  });
};

ko.applyBindings(new ViewModel());

https://jsfiddle.net/jtjozkax/37/

2 个答案:

答案 0 :(得分:0)

据我所知,导致此行为的不是页面加载本身,而是计算的observable依赖于其他可观察对象,在您的情况下,self.selectedDept。 Knockout发现计算所依赖的其他可观察量,实际上是selectedDept值的变化导致计算重新计算的原因。

您无法避免此行为,但可以通过添加保护条件(读取:if语句)来避免执行AJAX调用。我假设你的目标是在下拉列表中没有选择任何内容时阻止AJAX调用,而且,毕竟,这是实现这一目标的最直接的方法。

没有别的方法,只是因为如果你考虑它,计算的整个目的是在任何其他可观察的时候重新评估它依赖于变化,而不需要人工干预。

答案 1 :(得分:0)

if(!self.selectedDept()){return}

如果没有选择选项,则使用此if语句取消计算中的功能。

https://jsfiddle.net/jtjozkax/38/