How to bind the <ul> elements with new viewmodel data? - knockout.js

一个人想着一个人 提交于 2020-01-05 10:06:44

问题


I have a requirement where the view gets updated with new data. Here is the code for the view:

<table>
    <thead id="resultTableHeader">
        <tr style="text-align: center" data-bind="foreach: columns">
            <th style="text-align: center; height: 23px;" data-bind="visible: checked, text: header">
            </th>
         </tr>
    </thead>
    <tbody id="resultTableBody" data-bind="foreach: simpleSearchResultsArray">
        <tr>
            <td style="text-align: center; vertical-align: middle;">
                <span data-bind="text: $index()+1"></span>
            </td>
            <td style="text-align: center; vertical-align: middle;">
                <span data-bind="text: jobName"></span>
             </td>
             <td style="text-align: center; vertical-align: middle;">
                <span data-bind="text:qName"></span>
             </td>
        </tr>
    </tbody>
</table>
<button id="bindData1">bind data 1</button>
<button id="bindData2">bind data 2</button>

The view model for the same:

function SimpleSearchResults() {
    var self = this;
    self.index = ko.observable();
    self.jobName = ko.observable();
    self.qName = ko.observable();
};

function QuoteSimpleSearchVM() {
    var self = this;
    self.simpleSearchResultsArray = ko.observableArray([]);
    self.gridOptions = {
        columns: [{
            header: 'Index',
            dataMember: 'index',
            checked: ko.observable(true)
        }, {
            header: 'Job Name',
            dataMember: 'jobName',
            checked: ko.observable(true)
        }, {
            header: 'Quote Name',
            dataMember: 'qName',
            checked: ko.observable(true)
        }
       ]
    };

    self.Search = function (num) {
        var temparray = [];
        var bindData= [];

        // data1 and data2 to consider as info from service 
        var data1=  [{jobName: 'a', documentName: 'Quote1'},{jobName: 'b', documentName: 'Quote2'}];
        var data2=  [{jobName: 'c', documentName: 'Quote2'},{jobName: 'd', documentName: 'Quote4'}];

        if(num=="1") 
            bindData= data1;
        else
            bindData= data2;
        console.log(bindData);
            for (var k = 0; k < bindData.length; k = k + 1) {
                var temp = new SimpleSearchResults();
                temp.index = k + 1;
                temp.jobName = bindData[k].jobName;
                temp.qName = bindData[k].documentName;
                temparray.push(temp);
            }
            self.simpleSearchResultsArray = ko.observableArray([]);
            self.simpleSearchResultsArray = ko.observable(temparray);
        ko.applyBindings(QuoteSimpleSearchVMObj, document.getElementById("resultTableBody"));
    }
};

var QuoteSimpleSearchVMObj;
$(document).ready(function () {
     QuoteSimpleSearchVMObj = new QuoteSimpleSearchVM();
    ko.applyBindings(QuoteSimpleSearchVMObj.gridOptions, document.getElementById("resultTableHeader"));

    $("#bindData1").click(function(){
     alert("1");
        QuoteSimpleSearchVMObj.Search("1");
    });

     $("#bindData2").click(function(){
         alert("2");
        QuoteSimpleSearchVMObj.Search("2");
    });

});

The method Search in view model is called many times, on click of each time, there is new data which is updated in the view model. The same has to updated in the view.

My problem is, the first time view model is bound to the view, the data appears correct. Suppose the first time the ul in the view has 3 li's - the data is bound correct.

The next time i click Search, there is new data in View model, suppose the ul has two li's the second time, the data is bound 6 times in the view. Each li appearing thrice since the first seach had created 3 li's. How to solve this issue?

Hope i am clear with the question. Let me know if any more details is needed.

The link for jsfiddle: http://jsfiddle.net/KRyXR/91/ The link doesn't replicate the situation. Trying to make my problem clear. Consider data1 to be the data bound during first search, and data2 to be the data bound on clicking second time.

Thanks in advance.


回答1:


With knockout you don't need rebind the view on each model modification. That's mean you don't need to call this on each search :

self.simpleSearchResultsArray = ko.observableArray([]);
self.simpleSearchResultsArray = ko.observable(temparray);

Just call the "setter" of the observable and the view will changed.

 self.simpleSearchResultsArray(temparray);

I updated your fiddle in which I just bind only one times. I bound the whole viewmodel the whole table.

I hope it helps.

See fiddle



来源:https://stackoverflow.com/questions/17804656/how-to-bind-the-ul-elements-with-new-viewmodel-data-knockout-js

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!