2017-02-07 6 views
0

$ .observable (array) .insert()를 사용하여 항목을 목록에 추가하고 있습니다. 내보기를 업데이트하는 중입니다. 새 목록 항목이 DOM에 렌더링됩니다. 그러나 새 DOM 노드에서 click 이벤트를 발생시키고 싶습니다. 이벤트를 사용하여 클래스를 추가하여 항목을 확장하고 다른 수신기를 본문에 연결하여 영역을 닫을 수 있습니다.

둘 다

$.observable(_model.leadTimes).insert(leadTime); 
$leadTimes.find('.lead-time-data').last().find('.start-editing').click(); 

... 그리고

function watchLeadTimes() { 

    var changeHandler = function (ev, eventArgs) { 
     if (eventArgs.change === 'insert') { 

      $leadTimes.find('.lead-time-data').last().find('.start-editing').click(); 

     } 
    }; 

    $.observe(_model.leadTimes, changeHandler); 

} 

을 시도 내가 setTimeout(function() { $leadTimes.find('.lead-time-data').last().find('.start-editing').click(); }, 400);처럼 setTimout에 jQuery를 방법을 포장하는 경우 그 중 어느 것도, 그러나, 그것을했다 일을합니다. 이것은 jQuery의 click() 메소드가 호출되기 전에 DOM 렌더링이 어떻게 끝나지 않았을 때 타이밍 문제라고 생각하게 만듭니다.

확률이 좋으므로, 보리스, 라이브러리 및 모든 작업에 대해 감사드립니다. jsViews는 모 놀리 식 프레임 워크와 평범한 구식 jQuery 국수 사이의 훌륭한 중간 지점이라고 생각합니다!


편집 02/09/17

그것은 내 문제가 중복 클릭 이벤트였다 밝혀 - 나는 실수가 선택 직후 내 요소의 선택을 취소 클릭을 처리했다. 그러나 필자는 Borris의 링크 된 예를 따라 더 선언적인 접근법을 사용하기 위해 다시 작성하는 기회를 가졌습니다.

{^{for leadTimes}} 
    <tr class="lead-time-data" data-link="class{merge:~isSelected() toggle='editing'}"> 
     <span>{^{:daysLead}}</span> 
    </tr> 
{{/for}} 

을 그리고 이것은 JS :

지금 내 템플릿에 나는 계산 관찰, isSelected가 전환 할 .editing 클래스를 사용하고

function addNewLeadTimeClickHandler() { 

    var onNewLeadTimeClick = function() { 

     e.stopPropagation(); // this is what I was missing 

     var leadTime = { 
      daysLead: 1, 
      description: '' 
     }; 

     $.observable(_model.activityMapping.leadTimes).insert(leadTime); 
     selectLeadtime(_model.activityMapping.leadTimes.length -1); 

    } 
    $leadTimes.on('click', '.add', onNewLeadTimeClick); 

} 

function selectLeadtime(index) { 

    var addStopEditingClickHandler = function() { 

     var onClickHandler = function (event) { 
      if ($(event.target).closest('tr').hasClass('editing')) { 
       setHandler(); 
       return; 
      } 

      selectLeadtime(-1) 

     }; 

     function setHandler() { 
      var clickEvent = 'click.ActivityChangeRequestDetailController-outside-edit-row'; 
      $('html:not(.edit)').off(clickEvent).one(clickEvent, onClickHandler); 
     }; 

     setHandler(); 

    } 

    if (_model.selectedLeadtimeIndex !== index) { 
     $.observable(_model).setProperty('selectedLeadtimeIndex', index) 
     addStopEditingClickHandler(); 
    } 

} 
function isSelected() { 
    var view = this; 
    return this.index === _model.selectedLeadtimeIndex; 
} 
// isSelected.depends = ["_model^selectedLeadtimeIndex"]; 
// for some reason I could not get the above .depends syntax to work 
// ...or "_model.selectedLeadtimeIndex" or "_model.selectedLeadtimeIndex" 
// but this worked ... 
isSelected.depends = function() {return [_model, "selectedLeadtimeIndex"]}; 

답변

1

관찰 가능한 insert() 방법은 동기입니다. 목록 항목이 단순히 {^{for}}을 사용하여 렌더링되는 경우에는 동기식이기도하므로 setTimeout 또는 콜백을 사용할 필요가 없습니다. (이 같은 콜백을 사용할 수 있습니다,하지만 당신은이 시나리오를 필요가 없습니다.)

예를 http://www.jsviews.com/#samples/editable/tags를 참조하십시오 (코드 here) :

$.observable(movies).insert({...}); 
// Set selection on the added item 
app.select($.view(".movies tr:last").index); 

이 선택은 새로 삽입에 동 기적으로 추가지고 목.

렌더링의 다른 부분에 비동기 코드가 있습니까?

일반적으로 대리자 패턴을 사용하는 경우 추가 된 요소에 새 클릭 핸들러를 추가 할 필요가 없습니다. 예를 들어 동일한 샘플에서 동영상을 제거하는 클릭 핸들러는 "#movieList" 컨테이너에 추가되고 대리자 선택자 ".removeMovie" (code 참조)이 추가됩니다. 나중에 추가되는 영화에서도 작동합니다.

같은 시나리오는 http://www.jsviews.com/#link-events 참조 {{on}}를 사용하여 작동합니다 이 지침

+0

감사합니다 "선택기 인수가 나중에 추가되는 요소를 타겟팅 할 수 있습니다"; 나는 이것을 들여다 볼 것이다! 추가/제거하고 싶은 클릭 이벤트는 본문에 있습니다. 아이디어는 새 항목에 대한 클릭 이벤트를 트리거하여 추가 될 때 확장되고 사용자가 바깥 쪽을 클릭하여 닫을 수 있다는 것입니다. 위에서 링크 한 샘플과 비슷한 더 선언적인 접근 방식을 찾고 있습니다. – HowlingFantods