2013-07-05 5 views
4

를 사용하는 경우 여기 테스트 케이스가 있습니다. 위의 테스트 사례에서 1 페이지와 2 페이지 사이를 클릭하면 두 페이지가 비동기 적으로로드 된 다음 #main 요소의 내용이 바뀝니다. 프로세스에서 브라우저 기록 상태가 푸시되므로 위치 표시 줄의 URL이 업데이트되고 뒤로 버튼은 우리 위치를 되돌려 놓기로되어 있습니다.사라지는 knockout.js 바인딩() pjax

1 페이지의 목록은 knockout의 foreach 바인딩과 내가 정의한 List 모델로 채워져 있습니다 (헤드의 인라인 스크립트에 있음). 1 페이지의 ready에서 인라인 스크립트는 ko.applyBindings으로 실행되므로 목록이 채워집니다.

"항목 추가"버튼은 녹아웃이 목록에 추가되는 항목을보기 모델에 추가합니다.

몇 가지 항목을 추가 한 다음 2 페이지로 이동 한 다음 1 페이지로 돌아 가면 처음 3 개의 항목이 새로 추가되고 항목 추가 버튼이 계속 작동합니다. 유스 케이스에서는 괜찮습니다.

몇 가지 항목을 추가 한 다음 2 페이지로 이동했지만 브라우저의 뒤로 버튼을 사용하여 1 페이지로 돌아가는 것은 내 문제입니다. 새 항목은 계속 표시되지만 (브라우저의 뒤로 버튼을 사용할 때 의 사용이 중요 함) "항목 추가"버튼이 손상되었습니다. 새 항목을 observableArray에 푸시하는 코드는 확실히 실행되고 있지만 바인딩이 사라져서 녹아웃이 새 DOM 요소를 추가하지 못하는 것으로 보입니다.

popstate에서 ko.applyBindings 함수를 다시 실행할 수 없거나, 이제 녹아웃이 이제 기존 항목 각각을 목록의 각 항목에 대해 복제한다고 생각하고 그 후에 각각 "항목 추가" 여러 개의 새 항목을 제공합니다.

필자는 실종되었다는 느낌이 강하지 만 설명서에 도움이 될만한 내용은 찾을 수 없습니다. 어떤 도움이라도 대단히 감사 할 것입니다.

+0

DOM을로드 한 후 대신 페이지 상단에서 JavaScript를 정의하는 이유는 무엇입니까? –

+0

DOM이로드되기 전에 실행되는 유일한 부분은'List' 클래스의 정의입니다. 다른 덩어리는'ready' 이벤트에서 실행됩니다. DOM은 좋은 결과를 얻은 후에 시작됩니다. 그 질문에 대답합니까? http://api.jquery.com/ready/ -'$ (document) .ready (handler)'에 대한 대체 Jquery 구문입니다. – tremby

답변

1

UI에 뷰 모델을 바인딩 했음에도 불구하고 브라우저 기록이 원하는 위치에 페이지를 다시 작성하기 위해 어디에서나 브라우저 기록에 액세스 할 수 있기 때문에이 모델을 유지하지 않았기 때문에이 동작이 나타납니다. 이 동작은 브라우저의 내장 된 backforward 버튼을 사용하여 볼 수도 있습니다. 이 문제를 해결하기 위해 채택한 일반적인 패턴은 다음과 같습니다.

먼저 this을 변수에 할당하면 hassle later on이 절약됩니다. 뷰 모델은 다음과 같이 보일 것입니다.

function List(items) { 
    var self = this; 
    self.items = ko.observableArray(items) 
    self.addItem = function(text) { 
     self.items.push(text) 
    } 
} 

이제 뷰 모델의 현재 상태를 serialize하는 계산 된 관찰 가능을 만듭니다. 전적으로 구현 방법을 선택하는 것은 전적으로 귀하에게 달려 있습니다.

self.toJson = ko.computed(function(){ 
    /*** Serialise self.items() and return the string ***/ 
    return myJsonString; 
}); 

다음, 숨겨진 입력에 계산을 결합,이 뷰 모델이 너무 나중에 뷰 - 모델을 재수 수 있도록 폼 데이터에 유지되어 있는지 확인합니다.

<input id="serialisedItems" type="hidden" data-bind="value: toJson" value="[1,4,3]" /> 

마지막으로보기 모드를 $.ready()에서 다시 수화합니다.

$(function() { 
    var items = $('#serialisedItems').val(); 
    /*** Deserialise items before passing into the List ***/ 
    var list = new List(deserialisedItems); 
    ko.applyBindings(list); 
}); 

나는 또한 목록에 <input>의 값 속성을 설정하여 초기화 된이 시점에서 지적해야한다.

관련 문제