2017-02-21 51 views
0

У меня есть этот простой ViewModel:Нокаут afterRender выстреливает только один раз

export class ViewModel { 
    public arr : KnockoutObservableArray<Dtos>; 
    constructor() { 
     this.arr = ko.observableArray<Dtos>(null); 
     ko.applyBindings(this); 
     this.init(); 
    } 

    private init() { 
     var self = this; 
     ajaxCall().done(item => { 
       self.arr(item.Dtos);     
      }); 
    } 

    public initPlugins() { 
     jQuery(".external-events > li") 
      .each(function() { 
       if ($(this).attr("event-draggable") == "false") 
        return true; 
       jQuery(this).draggable({ 
       zIndex: 999, 
       revert: true, // will cause the event to go back to its 
       revertDuration: 0 // original position after the drag 
      }); 
     }); 
    } 
} 

Этот ВМ становится применен к этой разметке:

<ul class="external-events" data-bind="foreach: {arr, afterRender: initPlugins($data)}"> 
    <li event-draggable="false"> 
     <div class="bg-info"> 
      <span data-bind="text: Name"></span> 
     </div> 
     <ul class="external-events" data-bind="foreach: moreStuff"> 
      <li> 
       <div class="bg-info"> 
        <span data-bind="text: Name"></span> 
       </div> 
      </li> 
     </ul> 
    </li> 
</ul> 

Проблема заключается в том, что afterRender событие foreach связывания только сразу после ko.applyBindings, но DOM еще не готов, поэтому мы не сможем перетащить jQuery.ui.

Согласно документации Ko, afterRender должен стрелять каждый раз, когда observableArray (относящийся к соответствующему foreach) изменяется, но этого не происходит.

В конце концов я получил это работаю на инициализации перетаскиваемого в ajax.done после того как я заселить массив, но я чувствую, что это не правильный способ сделать это, и тем не менее, проблема все еще существует, afterRender не обстрел обновления массива.

Любые идеи были бы высоко оценены.

PS: массив я, очевидно, означает, ko.observableArray

ответ

1

Проблема заключается в вашем

foreach: {arr, afterRender: initPlugins($data)} 

afterRender ожидает функцию в качестве параметра, но вы вызываете функцию, вызвав ее с данными в качестве параметра, изменение это:

foreach: {arr, afterRender: initPlugins } 

afterRender метод будет вызываться с 2 параметрами нокаутом:

Массив вставленных элементов DOM, элемент данных, с которым они связаны

+0

спасибо, это работает! Есть ли какой-либо чистый способ получить доступ к ViewModel внутри afterRender? –