KnockoutJS의 템플릿 바인딩 오류를 디버깅하는 방법은 무엇입니까?


199

KnockoutJS 템플릿에서 디버깅 문제가 계속 발생합니다.

" items" 라는 속성에 바인딩하고 싶지만 템플릿에서 오타를 만들고 (기존이 아닌) 속성 " item"에 바인딩한다고 가정합니다 .

Chrome 디버거를 사용하면 나에게만 알려줍니다.

"item" is not defined.

바인딩 문제에 대한 자세한 정보를 얻는 데 도움이되는 도구, 기술 또는 코딩 스타일이 있습니까?

답변:


344

특정 범위에서 사용 가능한 데이터에 문제가있을 때 자주 수행하는 한 가지는 템플릿 / 섹션을 다음과 같이 바꾸는 것입니다.

<div data-bind="text: ko.toJSON($data)"></div>

또는 약간 더 읽기 쉬운 버전을 원할 경우 :

<pre data-bind="text: JSON.stringify(ko.toJS($data), null, 2)"></pre>

이렇게하면 해당 범위에 바인딩 된 데이터가 튀어 나와서 제대로 중첩되는지 확인할 수 있습니다.

업데이트 : KO 2.1 기준으로 다음과 같이 단순화 할 수 있습니다.

<pre data-bind="text: ko.toJSON($data, null, 2)"></pre>

이제 인수가에 전달되었습니다 JSON.stringify.


아 나도이 질문을해야합니다. console.log 데이터에 복잡한 코드를 사용했습니다. 이제 훨씬 쉬워졌습니다.
AlfeG

3
디버깅 팁에 대해 더 많이 생각하고 블로그 게시물을 만들어야 할 수도 있습니다. 염두에 두어야 할 또 다른 방법은 관측치 또는 계산 된 관측치에 대해 수동 구독을 수행하여 값이 변경되는 것을 보는 것입니다. 좋아하는 경우에 name관찰하고있다name.subscribe(function(newValue) { console.log("name", newValue); });
RP Niemeyer에

1
이 답변은 비교적 오래 되었기 때문에 console.log를 사용하고 객체 속성을 볼 때 디버거의 모든 기능을 사용하지 않는 이유는 무엇입니까? 예 : stackoverflow.com/a/16242988/647845
Dirk Boer

1
@ DirkBoer-console.log를 사용하는 것도 좋은 방법입니다. foreach시나리오 에서와 같이 내 요소 옆에 데이터를보고 싶을 때가 많으며 콘솔을 통해 선별하는 것보다 관련 렌더링 된 마크 업 내의 페이지에서 더 쉽게 볼 수 있습니다. 상황에 따라 다릅니다. : 여기에 내 생각을 좀 더 knockmeout.net/2013/06/... . 또한 바인딩과 같이 "깨끗한"버전을 로그에 기록 할 수 있습니다 console.log(ko.toJS(valueAccessor()).
RP Niemeyer

1
@RuneJeppesen-어떤 종류의 데이터를 직렬화하는지 잘 모르겠지만 다음과 같은 것이 도움이 될 수 있습니다. knockmeout.net/2011/04/…
RP Niemeyer

61

개발에 Chrome을 사용하는 경우 개발자 도구의 요소 패널에 직접 바인딩 컨텍스트를 표시하는 Knockoutjs 컨텍스트 디버거 라는 정말 훌륭한 확장 기능이 있습니다.


3
Firefox 나 Firebug에 이런 기능이 있었으면 좋겠습니다. 아무도 그런 것을 알고 있습니까?
Patrick Szalapski

지원이 중단 된 것으로 나타납니다. 복잡한 데이터 바인딩 구조를 사용하면 크롬이 충돌합니다. 대략 1 년 동안 내 프로젝트에서 근무한 적이 없습니다.
북극

오래전부터 KO에서 Ember로 옮겼지만 유감입니다.
neverfox

1
그것은 나를 위해 (주로) 잘 작동하며 정말 복잡한 구조가 있습니다. 나는 그것을 시도하지는 않았지만 확장에 대한 옵션에서 "충돌이 발생하면 직렬화 할 수없는 뷰 모델이있을 수 있습니다. 직렬화를 끌 수 있습니다." 메시지 아래에이 기능을 비활성화 할 수있는 확인란이 있습니다.
Grinn

매우 유용합니다.
Andrew

37

JavaScript 라이브러리 파일 어딘가에 bindingHandler를 한 번 정의하십시오 .

ko.bindingHandlers.debug = 
{
    init: function(element, valueAccessor) 
    {
        console.log( 'Knockoutbinding:' );
        console.log( element );
        console.log( ko.toJS(valueAccessor()) );
    }
};

단순히 다음과 같이 사용하십시오.

<ul data-bind="debug: $data">

장점

  • 요소 패널에 표시 와 같이 Chrome 디버거의 모든 기능을 사용하십시오.
  • 디버깅을 위해 DOM에 커스텀 요소를 추가 할 필요가 없습니다.

여기에 이미지 설명을 입력하십시오


32

도움이 될 수있는 다른 것을 찾았습니다. 바인딩을 디버깅하고 Ryans 예제를 사용해 보았습니다. JSON이 순환 루프를 발견했다는 오류가 발생했습니다.

<ul class="list list-fix" data-bind="foreach: detailsView().tabs">
 <li>
   <pre data-bind="text: JSON.stringify(ko.toJS($parent), null, 2)"></pre>
   <a href="#" data-bind="click: $parent.setActiveTab, text: title"></a>
 </li>
</ul>

그러나이 방법을 사용하면 데이터 바인드 값이 다음으로 대체되었습니다.

  <ul class="list list-fix" data-bind="foreach: detailsView().tabs">
    <li>
      <pre data-bind="text: 'click me', click: function() {debugger}"></pre>
      <a href="#" data-bind="click: $parent.setActiveTab, text: title"></a>
    </li>
  </ul>

이제 크롬 디버그 창이 열려있는 동안 PRE 요소를 클릭하면 멋지게 채워진 범위 변수 창이 나타납니다.

좀 더 나은 방법을 찾았습니다.

<pre data-bind="text: ko.computed(function() { debugger; })"></pre>

정말 유용합니다. <pre data-bind = "text : ko.toJSON ($ data, null, 2)"> </ pre>를 사용하여 녹아웃 순환 루프 및 면도기 마크 업 문제가 발생했습니다. <pre ... 디버거>는 완벽한 해결 방법입니다. 어떤 이유로 @ Html.CheckBox와 같은 RAZOR 입력이 ko.toJSON을 위반했습니다.
북극

20

단계별 가이드

  1. 이 가이드에서는 공식 KnockoutJS 예제 중 하나를 사용 합니다.
  2. 두 번째 연락처 (Sensei Miyagi) 뒤에있는 데이터를보고 싶다고 가정 해 봅시다.
  3. 두 번째 연락처의 첫 번째 입력 상자 ( 'Sensei'텍스트가있는 입력 상자)를 마우스 오른쪽 단추로 클릭하십시오.
  4. '요소 검사'를 선택하십시오. Chrome 개발자 툴바가 열립니다.
  5. JavaScript 콘솔 창을여십시오. >=Chrome 개발자 툴바의 왼쪽 하단에 있는 아이콘 을 클릭 하거나 Chrome 개발자 툴바에서 '콘솔'탭을 열거 나 Ctrl+ Shift+ 를 눌러 콘솔에 액세스 할 수 있습니다.J
  6. 다음 명령을 입력하고 Enter를 누르십시오. ko.dataFor($0)
  7. 이제 두 번째 행에 바인딩 된 데이터가 표시됩니다. 객체 왼쪽의 작은 삼각형을 눌러 객체 트리를 탐색하여 데이터를 확장 할 수 있습니다.
  8. 다음 명령을 입력하고 Enter를 누르십시오. ko.contextFor($0)
  9. 이제 루트와 모든 부모를 포함하여 전체 녹아웃 컨텍스트가 포함 된 복잡한 객체를 볼 수 있습니다. 복잡한 바인딩 표현식을 작성하고 다른 구문을 실험하려고 할 때 유용합니다.

위의 가이드를 따르는 경우의 출력 예

이 흑 마법은 무엇입니까?

이 트릭은 Chrome의 $ 0- $ 4 기능KnockoutJS의 유틸리티 방법 조합입니다 . 즉, 크롬을 사용하면 Chrome 개발자 도구 모음에서 선택한있는 요소를 기억하고 별칭에서 이러한 요소를 노출 $0, $1, $2, $3, $4. 브라우저에서 요소를 마우스 오른쪽 버튼으로 클릭하고 '요소 검사'를 선택하면이 요소가 자동으로 별칭 아래에서 사용 가능해집니다 $0. 이 트릭을 KnockoutJS, AngularJS, jQuery 또는 기타 JavaScript 프레임 워크와 함께 사용할 수 있습니다.

트릭의 다른 측면은 KnockoutJS의 유틸리티 메소드 ko.dataFor 및 ko.contextFor입니다.

  • ko.dataFor(element) -요소에 바인딩 할 수있는 데이터를 반환
  • ko.contextFor(element) -DOM 요소에 사용 가능한 전체 바인딩 컨텍스트를 리턴합니다.

Chrome의 자바 스크립트 콘솔은 모든 기능을 갖춘 자바 스크립트 런타임 환경입니다. 즉, 변수를 보는 것에 만 국한되지 않습니다. ko.contextFor콘솔에서 직접 뷰 모델 의 출력을 저장 하고 조작 할 수 있습니다 . 시도 var root = ko.contextFor($0).$root; root.addContact();하고 어떻게되는지 보십시오 :-)

행복한 디버깅!


7

내가 사용 하는 정말 간단한 것을 확인하십시오 .

function echo(whatever) { debugger; return whatever; }

또는

function echo(whatever) { console.log(whatever); return whatever; }

그런 다음 html에서 다음을 수행했습니다.

<div data-bind="text: value"></div>

그냥 교체하십시오

<div data-bind="text: echo(value)"></div>

더 고급 :

function echo(vars, member) { console.log(vars); debugger; return vars[0][member]; }

<div data-bind="text: echo([$data, $root, $parents, $parentContext], 'value')"></div>

즐겨 :)

최신 정보

또 다른 성가신 것은 정의되지 않은 값에 바인딩하려고 할 때입니다. 위의 예에서 데이터 객체가 {값이 아닌 {} : '일부 텍스트'}라는 것을 상상해보십시오. 이 경우 문제가 발생하지만 다음과 같이 조정하면 문제가 없습니다.

<div data-bind="text: $data['value']"></div> 

5

이러한 오류를 시각화하기 위해 knockthrough.js라는 github 프로젝트를 만들었습니다.

https://github.com/JonKragh/knockthrough

바인딩 오류를 강조 표시하고 해당 노드의 데이터 컨텍스트 덤프를 제공합니다.

여기 샘플로 재생할 수 있습니다 : http://htmlpreview.github.io/?https://github.com/JonKragh/knockthrough/blob/master/default.htm

여기에 이미지 설명을 입력하십시오

RP Niemeyer의 훌륭한 녹아웃 코드 샘플은이 점을 알려줍니다.


3

바인딩에 전달되는 데이터를 확인하는 가장 쉬운 방법 은 콘솔에 데이터를 삭제하는 것입니다.

<div data-bind="text: console.log($data)"></div>

녹아웃은 텍스트 바인딩에 대한 값을 평가 하고 (실제로 바인딩을 사용할 수 있음 ) $ data를 콘솔 브라우저 패널에 플러시합니다.


2

다른 모든 답변은 훌륭하게 작동합니다. 나는 내가하고 싶은 것을 추가하고 있습니다.

뷰에서 (ViewModel을 이미 바인딩했다고 가정) :

<div data-bind="debugger: $data"></div>

녹아웃 코드 :

ko.bindingHandlers.debugger = {
    init: function (element, valueAccessor) {
        debugger;
    }
}

이 디버거에서 코드를 일시 중지하고, element그리고 valueAccessor()가치있는 정보가 포함됩니다.


사용자 정의 바인딩이 필요하지 않습니다. 한 번 봐 가지고 stackoverflow.com/documentation/knockout.js/5066/...을
아담 Wolski에게

1
그래, 난 단지이 디버깅 스타일 ... 모든 사람들이 : 자신의 방법으로 그 일을 좋아하는 것 하나라고 지적하고 싶었 이런 식으로 할 수있는 명확한 필요가없는 동의
아 디트 MP

1

Visual Studio 및 IE에서 개발하는 경우이 data-bind="somebinding:(function(){debugger; return bindvalue; })()"기능 이 더 좋습니다 .eval 파일이 아닌 모든 바인딩이있는 스크립트로 이동하고 $ context $ data를 볼 수 있기 때문에 echo 기능 이 더 좋습니다. 이것은 Chrome에서도 마찬가지입니다);


Visual Studio 또는 IE와는 아무런 관련이 없습니다.
Serhiy

@Serhiy 크롬과 동일하지만 크롬에서는 파일없이 파일에 액세스 할 수 있다고 생각합니다 .VS에서 파일에 액세스 할 수 있다고 생각하지 않습니다.
Filip Cordas

0

이것은 나를 위해 작동합니다 :

<div data-bind="text: function(){ debugger; }()"></div>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.