2013-02-19 4 views
1

Новичок с Knockout, пытаясь это наше, чтобы увидеть, если я могу использовать его ... так голые со мной пожалуйста ....Обновить iScrollView после Knockout.js Еогеасп

Создание веб-приложений с JQuery Mobile/Knockout. JS/iScrollView. У меня есть список, который я заполняю, используя Knockout.js foreach. Я делаю запрос ajax, я получаю объект JSON, я вставляю его в свой наблюдаемый массив и обновления моей страницы, показывая мне все, как мне это нужно.

Теперь я хочу использовать iScrollView, так как список растет, у меня может быть приятный гладкий прокрутка вниз и использовать преимущества pullup или dropldown.

Я не могу понять, как правильно позвонить $(element).iscrollview('refresh') в нужное время, чтобы он отрегулировал размер окна прокрутки после того, как добавлено больше предметов.

Есть ли способ подождать, пока все предметы будут вставлены в DOM, а затем нажмите $(element).iscrollview('refresh').

Вот мой HTML

<div data-role="page" id="List" data-bind="event: {pageshow: loadItems}"> 
     <div data-role="content" data-iscroll> 
     <button value='load' data-bind="event: {click: loadItems}">load more stuff</button> 
     <ul data-role="none" class="list" data-bind="foreach: items"> 
      <li style="visibility:hidden"> 
       <div class="header"> 
        <h3 data-bind="text: name"></h3> 
        <p></p> 
       </div> 
       <div class="feat-list-btn feat-list-action"> 
        <img src="image.png" /> 
       </div> 
       <div class="feat-list-btn feat-list-comments"> 
        <img src="image.png" /> 
       </div> 
        <img data-bind="attr: {src: imageurl}" /> 
      </li> 
     </ul> 
     </div> 
</div> 

Вот как я получаю содержание:

function List(){ 
    var self = this; 
    self.loadItems = function(){ 
     $('#List [data-role="content"]').fadeOut(0); 
     $.mobile.showPageLoadingMsg(); 
      jQuery.ajax({ 
       url: mybackend.php', 
       type: 'POST', 
       data: 'howMany=10', 
       dataType: 'jsonp', 
       jsonp: 'jsoncallback', 
       success: function(data, textStatus, jqXHR){ 
         for (i=0;i<data.items.length;i++){ 
          self.items.push(data.items[i]); 
          } 
        }, 
       complete: function(){ 
        $.mobile.hidePageLoadingMsg(); 
        } 
       }); 
     }; 
    self.items = ko.observableArray(); 
    self.updateScroller = function(){ 
     //???????? 
     }; 
    } 

я могу решить эту проблему, делая

setTimeout(function(){$('#List [data-role="content"]').iscrollview('refresh');}, 1000); 

Но я предпочел бы не полагаться на setTimeOut, чтобы получить такие вещи, как это сделано ...

Любые предложения или критика была бы оценена в этом случае ...

Спасибо ..

ответ

0

Так что это было намного проще, чем я думал, я понял, что происходит то, что мои изображения еще не загружены в память что означало, что в разметке, созданной нокаутом, не было НИЧЕГО, где изображения должны были давать объем. Я помещал изображения наполнителя, взятые из локального источника, но они не обязательно будут иметь правильные размеры, и я могу иметь неточную высоту прокрутки.

То, что я пробовал и в конечном итоге закончил работу, состоял в том, чтобы предварительно загрузить изображения, прежде чем добавлять их в ko.Observablearray. так что я написал этот SimPE прелоадер изображения как плагин JQuery:

(function($) { 
    $.fn.preload = function(callback) {   
     var count = 0, 
      $this = this; 
     for (i=0;i<this.length;i++){   
      var image = new Image();   
      $(image).on('load error', function(e){count++; if (count === $this.length){if ($.isFunction(callback)){callback.call()}}}); 
      image.src = this[i];; 
      } 
     } 
    })(jQuery); 

Это в основном позволяет мне ждать, пока все мои изображения не были загрузки в память

Затем я добавляю к моему ko.Observablearray, который вставляет моя разметка с изображениями на месте ... а затем вызвать ОБНОВИТЬ так:

 success: function(data, textStatus, jqXHR){ 
      var myImages = []; 
      for (i=0;i<data.urls.length;i++){ 
       myImages.push(data.urls[i]); 
       } 
       $(myImages).preload(function(){ //only execute insertion after all images are preloaded into memory 
        for (i=0;i<data.items.length;i++){ 
         self.items.push(data.items[i]); 
         } 
         $('#featList [data-role="content"]').iscrollview('refresh');//refresh iScroll 
         $.mobile.hidePageLoadingMsg(); 
        });   
      }, 

чем, вероятно, может быть оптимизирована несколько больше, но это рабочий раствор ...

0

Просто вставьте эту строку:

$('#List [data-role="content"]').iscrollview('refresh'); 

после for цикла в успех обратного вызова:

success: function(data, textStatus, jqXHR){ 
    for (i=0;i<data.items.length;i++){ 
     self.items.push(data.items[i]); 
    } 
    $('#List [data-role="content"]').iscrollview('refresh'); 
}, 
+0

Почти ...Я понял это вчера вечером, и я отправлю ответ через секунду ... это заставит разметку писать до загрузки изображений, что означает, что мой iScroll будет подстраиваться под размер этой разметки, содержащей NO images .. слишком короткий –

Смежные вопросы