Как использовать привязку данных knockout.js, когда запрос ajax периодически автоматически обновляется?

В моем приложении я периодически делаю вызов ajax один раз каждые 5 секунд, чтобы получить новое обновление с сервера.

Мои данные ajax с сервера - это массив JSON, который выглядит так: [ {    "foo": "valx",    "bar": "valy"

}, {    "foo": "valw",    "bar": "valz" } ]

Мой код ajax:

(function update() {

    $.ajax({
        type : 'GET',
        url : url,
        data : {

        },
        dataType : "json",
        global : false,
        success : function(content, textStatus, jqXHR) {
        myViewModel = content;
        ko.applyBindings(myViewModel);

        },
        complete: function() {

         setTimeout(update, 5000);
          },

        error: function( xhr, textStatus ) {

            }
    });
    })();                       

Мой HTML:

<tbody data-bind="foreach: myViewModel">
                        <tr>
                            <td data-bind="text: foo"></td>
                            <td data-bind="text: bar"></td>
                        </tr>
                    </tbody>

Но это не работает, и я получаю сообщение об ошибке после первого вызова ajax: Вы не можете применять привязки несколько раз к одному элементу.

Ответ 1

Ты близко. Вы вызываете только applyBindings один раз. Вместо этого вы должны установить свойство observable в вашей модели представления.

Вот как вы можете настроить свою модель просмотра:

function ViewModel() {
    var self = this;

    self.data = ko.observableArray();
};

var viewModel = new ViewModel();

ko.applyBindings(viewModel);

Затем, когда у вас есть новые данные (например, в вашем вызове ajax):

$.ajax({
    success : function(content, textStatus, jqXHR) {
        viewModel.data(content);
    }
});

Примечание. Вы можете установить данные несколькими способами. Если вы хотите, чтобы ваше время было за пределами модели просмотра, вы можете использовать экземпляр модели представления (в моем примере, viewModel) для доступа к свойствам и их обновления. Вы можете поместить синхронизированное событие в свою модель просмотра, если хотите, а затем просто вызовите self.data(content) (или что-то подобное).