2014-03-13 98 views
0

我正在建立一個包含上一個和下一個按鈕的圖像幻燈片。圖像是從json對象中獲取的。使用<img data-bind="attr: { src: images } />時圖像顯示正常,沒有任何問題,但只要我應用return { controlsDescendantBindings: true },圖像就會停止顯示。並且<img data-bind="attr: { src: images } />上的數據綁定不再起作用。Knockout.js自定義綁定的幻燈片:圖像不顯示

你知道發生了什麼?

非常感謝

HTML:

<!-- carousel --> 
<div class="carousel" data-bind="carousel: true"> 
    <div class="controls"> 
     <a href="#" class="prev">Prev</a> 
     <a href="#" class="next">Next</a> 
    </div> 
    <div class="viewport"> 
     <!-- trip() represent the json object, but it's confidential --> 
     <ul data-bind="foreach: trip().boat.decks"> 
      <li><a href="#"><img class="image" data-bind="attr: { src: images }" /></a></li> 
     </ul> 
    </div> 
</div> 
<!-- carousel --> 

淘汰賽/ JS:

// binding for carousel 
ko.bindingHandlers.carousel = { 
    init: function (element, valueAccessor) { 
     var $carousel = $(element), 
      $viewport = $carousel.find('.viewport'), 
      $controls = $carousel.find('.controls'), 
      $prev = $controls.find('.prev'), 
      $next = $controls.find('.next'), 
      $slideList = $viewport.find('ul'), 
      $slide = $slideList.find('li'); 

     console.log('carousel starting...'); 
     console.log('what is element: ', element); 
     console.log('what is $element: ', $(element)); 

     // put active on 1st slide 
     $slide.first().addClass('active'); 

     //TODO: prev btn 
     $carousel.on('click', '.prev', function (e) { 
      e.preventDefault(); 

      console.log('Prev btn carousel clicked!'); 

      $viewport.find('.active').removeClass('active').prev().addClass('active'); 

      // if arrived at 1st slide, start again from last slide 
      if ($viewport.find('.active').index() < 0) { 
       $slide.first().removeClass('active'); 
       $slide.last().addClass('active'); 
      } 
     }); 

     //TODO: next btn 
     $carousel.on('click', '.next', function (e) { 

      e.preventDefault(); 

      console.log('Next btn carousel clicked!'); 

      $viewport.find('.active').removeClass('active').next().addClass('active'); 

      // if arrived at last slide, start again from 1st slide 
      if ($viewport.find('.active').index() < 0) { 
       $slide.last().removeClass('active'); 
       $slide.first().addClass('active'); 
      } 
     }); 

     return { 
      controlsDescendantBindings: true 
     }; 
    } 
}; 
+0

如果您希望Knockout以正常方式處理子綁定,爲什麼要返回'controlsDescendantBindings:true'? –

回答

0

當您返回controlsDescendantBindings: true你告訴淘汰賽不要在子元素進行綁定,這就是爲什麼無子元素綁定。該documentation on creating custom bindings that control descendant bindings指出:

通常情況下,使用controlsDescendantBindings綁定也會打電話給ko.applyBindingsToDescendants(someBindingContext,元素),以對一些修飾的結合範圍內應用後裔綁定。

但是,在你的情況下,你永遠不會打電話給ko.applyBindingsToDescendants,所以Knockout永遠不會綁定子元素。

我不確定你爲什麼試圖控制後代綁定,但你需要刪除它或確保你打電話給你ko.applyBindingsToDescendants如果你希望Knockout綁定子元素。

+0

感謝您的回覆@ robert.westerlund。我使用的是'controlsDescendantBindings:true',因爲我想讓'prev'和'next'按鈕上的'click'事件起作用,如果我不使用它,它們將不起作用。除非我對custome綁定的理解偏離軌跡...... – Shaoz

+1

即使您想要監聽子元素上的事件,您也不需要執行'controlsDescendantBindings:true'(儘管對於動態添加的元素,您應該使用'on '與一個選擇和範圍爲父母)。不過,我可能會使用[視圖模型和模板版本](http://jsfiddle.net/7bsVd/)或使用現有的jQuery UI插件或類似的bindingHandler來創建實際輪播。 –

+0

感謝您的建議@ robert.westerlund。我是Knockout的初學者,所以我不太瞭解自定義綁定 – Shaoz