在 Knockout.js 中异步应用绑定

Posted

技术标签:

【中文标题】在 Knockout.js 中异步应用绑定【英文标题】:Asynchronously Apply Bindings in Knockout.js 【发布时间】:2017-12-29 23:29:19 【问题描述】:

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

当要填充的数据在函数中是静态的时,该代码可以完美运行,但是在使用异步 ajax 调用时无法正常工作,因为绑定是在收到响应之前执行的。

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

淘汰赛

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');
    );

【问题讨论】:

【参考方案1】:

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

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... 但我想这是一个品味问题。

【讨论】:

谢谢您,这是一个非常有帮助且超级快速的回复!你我的朋友拯救了这一天!

以上是关于在 Knockout.js 中异步应用绑定的主要内容,如果未能解决你的问题,请参考以下文章

Knockout.js v2.3.0 错误“您不能将绑定多次应用于同一元素”

用于在 url 中查找部分字符串的 Knockout.js 数据绑定

knockout.js - 数据绑定文本默认值

Knockout.JS如何绑定dom元素绑定

如何在动态添加的内容中绑定 knockout.js 中的事件?

Visual Studio 数据绑定属性突出显示 [knockout.js]