javascript - 在 Knockout.js 中异步应用绑定(bind)

标签 javascript json asynchronous knockout.js jquery-select2

我很难理解如何使用 knockoutJS 异步绑定(bind)级联 Select2 下拉字段。

当要填充的数据在函数内是静态的时,代码可以完美运行,但是在使用异步 ajax 调用时则不起作用,因为绑定(bind)是在接收到响应之前执行的。

由于我是 knockout.js 初学者,任何人都可以引导我走向正确的方向或发现问题吗?

knockout

var viewModel = {
    togaMakers: buildData(),
    selectedInstitution : ko.observable(),
    selectedLevel : ko.observable(),
    selectedFaculty : ko.observable()
};

viewModel.togaLevels = ko.computed(function(){
    if(viewModel.selectedInstitution()){
        var make = ko.utils.arrayFirst(viewModel.togaMakers,function(item){
            //console.log(item.text,viewModel.selectedInstitution());
                return item.text===viewModel.selectedInstitution();          
        });
        return make.childOptions;
    } 
});

viewModel.togaFaculties = ko.computed(function(){
    if(viewModel.selectedLevel()){
        var type = ko.utils.arrayFirst(viewModel.togaLevels(),function(item){
            //console.log(item.text,viewModel.selectedLevel());
                return item.text===viewModel.selectedLevel();
          //console.log("Answer:" + item);
        });
        return type.childOptions;
    } 
});
ko.cleanNode(viewModel);
ko.applyBindings(viewModel);

buildData()

function buildData() {
    var gotData = getData();

    return gotData.then(function() {
        console.log('step 4 - return result');
        returnData = gotData;
        return returnData;
    });
}

getData()

// Get all data from ajax call
function getData() {
    var data = { 'action': 'get_data' };
    var deferred = new jQuery.Deferred();

    return jQuery.post(ajaxurl, data, function(response) {
        // console.log(response);
        console.log('step 1 - parse ajax data');
        var obj = JSON.parse(response);
        console.log('step 2 - process received data');
        results = processData(obj);
    }).done(function() {
        console.log('step 3 - ajax parsing & processing data done');
        console.log(results);
        deferred.resolve(results);
        return deferred;
    }).fail(function() {
        console.log('fail');
    });
}

最佳答案

buildData 需要返回一个 observable 以便在数据更改后自动更新您的绑定(bind):

function buildData() {
  var dataContainer = ko.observableArray([]);

  getData().then(function(newData) {
    console.log('step 4 - return result');
    dataContainer(newData);
  });

  return dataContainer; // Initially empty array
};

我个人会首先在您的 viewModel 中定义该数组,然后通过引用它在 then 中写入它。如果您使用基于类/实例的方法可能会有所帮助,这样您就可以使用 this 引用 dataContainer...但我想这是一个品味问题。

关于javascript - 在 Knockout.js 中异步应用绑定(bind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45279559/

相关文章:

python - Postgres 9.4 Django 1.9 获取所有 json 键

json - JQ 创建 JSON 键值对

react-native - React Native不显示异步功能错误

javascript - jquery 的 attr() 是异步的吗?

javascript - Node.js 中无错误时短路异步流的模式

javascript - Javascript 和 Java 的 Web 套接字问题 - 未捕获的 DOMException : An attempt was made to use an object that is not, 或不再可用

c# - Kendo 网格、虚拟滚动、页面大小和聚合

javascript - 单击 Ext.menu.Menu 中的菜单项

javascript - GSAP 重复延迟数组?

javascript - js解析json多个元素与单个元素