2014-12-03 3 views
2

Я сошел с ума, пытаясь понять это. Я видел множество запутанных и трудно реализуемых примеров заполнения вычисленных наблюдаемых в Knockout, когда асинхронный вызов завершен, но я не могу заставить его работать, используя шаблон раскрытия модуля.Отложить асинхронное вычисление наблюдаемого

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

eh.vm.skills = function() { 

    //#region Public Variables 

    var skills = ko.computed({ 
      read: function() { 
       $.get("http://horodyski.me/api/skills", function (data) { 
        return data; 
       }); 
      }, 
      deferEvaluation: true 
     }), 
    //#endregion 


    //#region Public Interface 

    return { 
     skills: skills 
    } 

    //#endregion 
}; 

И это HTML связывание:

<ul class="skills skills-top" id="skills" data-bind="foreach: skills"> 
    <li> 
     <i data-bind="text: $index"> </i> 
     <span data-bind="text: $data.Title"></span> 
    </li> 
</ul> 
<script src="//cdn.horodyski.me/js/vm.js"></script> 
<script> 
    ko.applyBindings(eh.vm.skills, $("#skills")[0]); 
</script> 

То, что я хотел бы сделать это на создание переменной skills, выборки данных и вернуть его. Данные уже возвращаются в массив (например: [{Title: "ABC"}]), но он, похоже, не связывается. Я попробовал вместо этого использовать $.when().then() (как я предпочитаю), но даже когда отложенное значение отложено, оно все равно не будет обновляться.

Действительно сложная часть для меня - переменная область. Сложность модуля показывает, когда дело доходит до объема. Я трепетал над этим в течение 3 часов ... если кто-то может вести меня в правильном направлении, это будет оценено по достоинству.

Редактировать Использование Knockout 3.1 (если это поможет)

ответ

6

read Вашего обратного вызова неправильно.

Обратный вызов:

function (data) { 
    return data; 
} 

Мертв код, его возвращения данных в функции JQuery, которая называется этот обратный вызов, который собирается делать ничего с ним.

Вы должны вернуть отсроченные себя:

read: function() { 
    return $.get("http://horodyski.me/api/skills"); 
} 

Вы также нуждаются в асинхронном расширителе здесь: http://smellegantcode.wordpress.com/2012/12/10/asynchronous-computed-observables-in-knockout-js/

ko.extenders.async = function(computedDeferred, initialValue) { 
    var plainObservable = ko.observable(initialValue), currentDeferred; 
    plainObservable.inProgress = ko.observable(false); 

    ko.computed(function() { 
     if (currentDeferred) { 
      currentDeferred.reject(); 
      currentDeferred = null; 
     } 

     var newDeferred = computedDeferred(); 
     if (newDeferred && (typeof newDeferred.done == "function")) { 
      plainObservable.inProgress(true); 
      currentDeferred = $.Deferred().done(function(data) { 
       plainObservable.inProgress(false); 
       plainObservable(data); 
      }); 
      newDeferred.done(currentDeferred.resolve); 
     } else { 
      plainObservable(newDeferred); 
     } 
    }); 

    return plainObservable; 
}; 

Используется как:

var skills = ko.computed(...).extend({ async: null }); 

Если вы хотите подключить в JSON, прежде чем он будет передан вашему представлению:

var skillsJson = ko.computed(...).extend({ async: null }); 
var skills = ko.computed(function() { 
    return transformData(skillsJson()); 
}; 

Или:

var skills = ko.computed(function() { 
     return $.get("url").then(function (data) { 
      return transform(data); 
     }); 
    }); 
+1

Так близко. Мне было интересно, если 'async' был встроенным расширителем. Я не могу найти его в 'ko.extenders', и онлайн-документация близка к нулю. Тем не менее ... он все еще просто возвращает объект обещания к «навыкам» – EHorodyski

+0

Ах, это так. Извинения У меня был кошмар, отвечая на этот вопрос ... Спасибо за ваше терпение. Будет обновляться снова. –

+0

Не заботьтесь о человеке, я полностью благодарен за помощь. Вы получите правильную проверку: «) – EHorodyski