3

나는 Knockout로 만든 테이블이 나는 테이블에 항목을 배치하는 drag'n'drop 인터페이스를 구현하고 싶습니다. 기본적으로, 나는 테이블에 드롭 할 수있는 새 항목을 생성하는 div가 있습니다. 또한 이미 테이블에있는 항목을 드래그 할 수 있어야합니다.녹아웃 드래그 앤 드롭 테이블

기존 솔루션을 조사해 보았는데 가장 좋은 솔루션 중 하나는 rniemeyer's이지만 jQueryUI의 sortable 위젯을 사용합니다.

이것이 나를 위해 작동하지 않는 이유는 은 지정된 위치의 배열에 개의 새 요소를 삽입하지만이를 덮어 써야합니다.

그래서 내 자신 만의 맞춤 바인딩을 쓰기 시작했지만 다른 벽에 부딪 혔습니다. 생성 된 항목을 표에 놓으면 새 요소를 만들고 클래스, 속성을 추가하고 td에 추가하지만 해당 요소의 녹아웃 바인딩은 수행되지 않습니다.

코드 :

var dragData = {}; 

    ko.bindingHandlers.draggable = { 
     init: function (element, valueAccessor) { 
      var value = ko.utils.unwrapObservable(valueAccessor()); 
      var dragElement = $(element); 
      var dragOptions = { 
       revert: true, 
       revertDuration: 0, 
       start: function (event, ui) { 
        dragData = value.data; 
       } 
      }; 

      dragElement.draggable(dragOptions).disableSelection(); 
     } 
    }; 

    ko.bindingHandlers.droppable = { 
     init: function (element, valueAccessor) { 
      var value = ko.utils.unwrapObservable(valueAccessor()); 
      var dropElement = $(element); 
      var dropOptions = { 
       drop: function (event, ui) { 
        var div = $('<div/>', { 
         'data-bind': "draggable: " + 
          "{ " + 
           "revert: true," + 
           "revertDuration: 0," + 
           "opacity: 0.75," + 
           "data: " + 
            "{" + 
             "selectedSubject: " + dragData.selectedSubject + "," + 
             "selectedTeacher: " + dragData.selectedTeacher + "," + 
             "numberOfClasses: 1" + 
            "}" + 
          "}" 
        }).addClass('schedule-item panel-info'); 

        $(div).append('<div class="row">' + dragData.selectedSubject + '</div>'); 
        $(div).append('<div class="row">' + dragData.selectedTeacher + '</div>'); 

        dropElement.html(div); 
       } 
      }; 

      if (value.accept) 
       ko.utils.extend(dropOptions, { accept: value.accept }); 

      if (value.hoverClass) 
       ko.utils.extend(dropOptions, { hoverClass: value.hoverClass }); 

      if (value.tolerance) 
       ko.utils.extend(dropOptions, { tolerance: value.tolerance }); 

      dropElement.droppable(dropOptions); 
     } 

ko.applyBindings() 반환이 오류 : You cannot apply bindings multiple times to the same element.

데이터가 완료되지 않은 바인딩하기 때문에, 테이블의 항목은 undraggable 남아있다.

데이터 바인딩을 수행 할 수있는 방법이 있습니까? 또는 jQuery UI sortable 위젯에 '오버라이드'메커니즘을 구현할 수있는 방법이 있습니까? 당신이 KO Template bindings을 시도 foreach는 바인딩 2 절 보라처럼

+0

jquery sortable plugin의 업데이트 이벤트를 사용하여 항목이 삭제 된 위치를 관찰하고 해당 위치 바로 다음에 오는 항목을 간단하게 분리 해 보았습니까? 드롭이 끝나면 그 위치의 아이템을 효과적으로 "덮어 씁니다". 유일한 단점은 이벤트가 시작되기 전에 배열의 길이가 잠시 증가하고 + 1 위치의 항목을 삭제한다는 것입니다. –

+0

나는 그것을 시도해 보았지만 실제로는 직관력이 없다. 사용자가 문제를 겪을 것이라는 느낌이 든다. 이 솔루션은'sortable' 위젯이 없어야 할 것으로 보인다. – Sljux

+1

이 코드는'ko.applyBindings'을 호출하지 않습니다. 어쨌든 데이터 바인딩 속성을 구축하는 대신 ko.applyBindingToNode (theCreatedDiv, theBindings)를 사용하는 것이 좋습니다. – user2864740

답변

0

그것은 나에게 보인다. 템플릿은 지정한 패턴에 따라 새로 드롭 된 각 객체를 렌더링하고 새 바인딩은 자동으로 새 요소에 추가됩니다.

당신이 코를 우회하고, DOM에 직접 새로운 요소를 삽입하고, 녹아웃이 경우 새로운 바인딩을 추가하지 않는 것처럼 보인다.