2012-03-04 1 views
7

У меня есть список вложений на странице, которая создается с помощью jQuerycall и Knockout JS.Обновление списка после вызова ajax с нокаутом JS

Мой HTML выглядит (это раздели назад):

<tbody data-bind="foreach: attachments"> 
    <tr> 
    <td data-bind="text: Filename" /> 
    </tr> 
</tbody> 

У меня есть функция, которая получает список приложений, который возвращается в качестве ответа JSON:

$(function() { 
    getFormAttachments(); 
}); 

function getAttachments() { 
    var request = $.ajax({ 
    type: "GET", 
    datatype: "json", 
    url: "/Attachment/GetAttachments" 
    }); 

    request.done(function (response) { 
    ko.applyBindings(new vm(response)); 
    }); 
} 

Мой вид модели выглядит так:

function vm(response) { 
    this.attachments = ko.observableArray(response); 
}; 

Существует кнопка обновления, которую можно использовать, чтобы обновить этот список, потому что более возможно, были добавлены вложения времени/удалены:

$(function() { 
    $("#refresh").on("click", getAttachments); 
}); 

Первоначальный рендеринг списка вложений в порядке, однако, когда я звоню getAttachments снова с помощью кнопки обновления щелкните список добавляется (на самом деле каждый элемент дублируется несколько раз).

Я создал jsFiddle, чтобы продемонстрировать эту проблему здесь:

http://jsfiddle.net/CpdbJ/137

Что я делаю неправильно?

+0

Kev - хороший пост. Я все еще немного смущен этим. Новое для нокаута. У меня возникают аналогичные проблемы, просто загружая ViewModel с данными AJAX при загрузке страницы. Я уверен, что мне не хватает крошечного, но серьезного момента. одна вещь, которая меня смущает, - это некоторые уроки, показывающие «viewmodel» как объект (например, «var viewmodel = {something: ko.observable()}»), а другие как функция (например, функция ViewModel() {this.something = ko.observable()} ') - любые предложения? –

+0

@ one.beat.consumer - см. Мой последующий вопрос: http://stackoverflow.com/questions/9589419/difference-between-knockout-view-models-declared-as-object-literals-vs-functions - ответ и комментарии ниже должны сделать вещи более ясными. Я бы рекомендовал потратить 25 долларов США и посмотреть это: http://www.pluralsight-training.net/microsoft/Courses/TableOfContents?courseName=knockout-mvvm – Kev

+0

Я проверю ваш другой вопрос; Спасибо. У меня есть подписка на множественный доступ, и я смотрел ее 2-3 раза ... они едва поцарапали поверхность, и большая часть ее уже устарела, когда 2.0 отсутствует, они использовали 1.2 или 1.3 beta ... –

ответ

10

Вот скрипка, которая фиксирует ваш образец. Самая большая проблема заключалась в том, что вы несколько раз называли «applyBindings». Обычно вы вызываете applyBindings при загрузке страницы, а затем страница будет взаимодействовать с View Model, чтобы заставить Knockout обновлять части вашей страницы.

http://jsfiddle.net/CpdbJ/136

HTML

<table> 
    <thead> 
     <tr><th>File Name</th></tr> 
    </thead> 
    <tbody data-bind="foreach: attachments"> 
     <tr><td data-bind="text: Filename" /></tr> 
    </tbody> 
</table> 
<button data-bind="click: refresh">Refresh</button> 

Javascript

$(function() { 
    var ViewModel = function() { 
    var self = this; 

    self.count = 0; 
    self.getAttachments = function() { 
     var data = [{ Filename: "f"+(self.count*2+1)+".doc" }, 
        { Filename: "f"+(self.count*2+2)+".doc"}]; 
     self.count = self.count + 1; 
     return data; 
    } 

    self.attachments = ko.observableArray(self.getAttachments()); 

    self.refresh = function() { 
     self.attachments(self.getAttachments());   
    } 
    }; 

    ko.applyBindings(new ViewModel()); 
}); 

-

Вы также можете посмотреть на отображение плагина - http://knockoutjs.com/documentation/plugins-mapping.html. Это может помочь вам преобразовать JSON в View Models. Кроме того, он может назначить свойство «ключом» для объекта ... это будет использоваться для определения старых и новых объектов при последующих сопоставлениях.

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

http://jsfiddle.net/wgZ59/276

Примечания: Я использую «обновление», как часть моих правил отображения, но только так я могу войти в консоль. Вам нужно будет добавить это только в том случае, если вы хотите настроить способ обновления объектов плагина.

+0

Как это работает, если скажем, у меня нет данных, и мне нужно вызвать метод Ajax и его GET? – Vyache

+0

Просто измените вызов getAttachments, чтобы сделать вызов AJAX, а в обратном вызове задайте результаты непосредственно в массиве наблюдаемых вложений. Обновление просто вызовет self.getAttachments(). вложения будут инициализированы пустым, а затем вы можете сразу вызвать self.getAttachments(), чтобы сделать первый вызов AJAX. Как только обратный вызов задает результаты, Knockout позаботится об обновлении пользовательского интерфейса. –

+0

Хмм, по какой-то причине я не могу обновить свои данные этим методом, см. Мой вопрос: http://stackoverflow.com/questions/21558075/how-do-i-update-my-model-using-ajax-and -отображением-плагин – Vyache