Làm cách nào để gỡ lỗi lỗi liên kết mẫu cho KnockoutJS?


199

Tôi liên tục gặp vấn đề với việc gỡ lỗi trong các mẫu KnockoutJS.

Nói rằng tôi muốn liên kết với một thuộc tính có tên " items" nhưng trong mẫu tôi tạo lỗi chính tả và liên kết với thuộc tính (không tồn tại) " item".

Sử dụng trình gỡ lỗi Chrome chỉ cho tôi biết:

"item" is not defined.

Có công cụ, kỹ thuật hoặc phong cách mã hóa nào giúp tôi có thêm thông tin về vấn đề ràng buộc không?

Câu trả lời:


344

Một điều mà tôi làm khá thường xuyên khi có vấn đề với dữ liệu nào có sẵn ở một phạm vi nhất định là thay thế mẫu / phần bằng một cái gì đó như:

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

Hoặc, nếu bạn muốn một phiên bản dễ đọc hơn một chút:

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

Điều này sẽ phun ra dữ liệu bị ràng buộc ở phạm vi đó và cho phép bạn chắc chắn rằng bạn đang lồng mọi thứ một cách thích hợp.

Cập nhật: kể từ KO 2.1 , bạn có thể đơn giản hóa nó thành:

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

Bây giờ các đối số được truyền vào JSON.stringify.


ồ Tôi cũng cần phải hỏi câu hỏi này. Đã sử dụng đoạn mã phức tạp để dữ liệu console.log. Bây giờ nó dễ dàng hơn nhiều.
AlfeG

3
Tôi phải suy nghĩ nhiều hơn về các mẹo gỡ lỗi và có thể tạo một bài đăng blog. Một điều khác mà tôi nghĩ đến là thực hiện đăng ký thủ công chống lại các vật quan sát hoặc các vật thể quan sát được tính toán để xem giá trị thay đổi. Giống như nếu namelà một việc làm có thể quan sát đượcname.subscribe(function(newValue) { console.log("name", newValue); });
RP Niemeyer

1
Có thể bởi vì câu trả lời này tương đối cũ, nhưng tại sao không sử dụng console.log và sử dụng toàn bộ sức mạnh của trình gỡ lỗi để xem các thuộc tính đối tượng? Xem tức là: stackoverflow.com/a/16242988/647845
Dirk Boer

1
@DirkBoer - sử dụng console.log cũng có thể là một cách tuyệt vời. Nhiều lần tôi muốn xem dữ liệu bên cạnh các yếu tố của mình như trong một foreachkịch bản và tôi thấy nó dễ nhìn thấy hơn trên trang trong phần đánh dấu được kết xuất có liên quan hơn là sàng lọc qua bảng điều khiển. Chỉ phụ thuộc vào tình hình. Một số suy nghĩ của tôi ở đây: knmeout.net/2013/06/ . Ngoài ra, bạn có thể muốn đăng nhập một phiên bản "sạch" trong ràng buộc của bạn như thế nào console.log(ko.toJS(valueAccessor()).
RP Niemeyer

1
@RuneJeppesen - Tôi không chắc bạn sắp xếp loại dữ liệu nào, nhưng một cái gì đó như thế này có thể giúp: knmeout.net/2011/04/14
RP Niemeyer

61

Nếu bạn đang sử dụng Chrome để phát triển, có một tiện ích mở rộng thực sự tuyệt vời (mà tôi không liên kết) được gọi là trình gỡ lỗi bối cảnh Knockoutjs hiển thị cho bạn bối cảnh ràng buộc trực tiếp trong bảng Thành phần của Công cụ dành cho nhà phát triển.


3
Tôi ước Firefox hoặc Fireorms có cái này. Bất cứ ai biết về một điều như vậy?
Patrick Szalapski

Xuất hiện hỗ trợ đã bị loại bỏ. Làm cho chrome bị sập nếu bạn sử dụng cấu trúc liên kết dữ liệu phức tạp. Đã không làm việc cho bất kỳ dự án của tôi trong khoảng một năm nay.
Bắc Cực

Rất tiếc khi nghe nó, mặc dù từ lâu tôi đã chuyển từ KO sang Ember.
neverfox

1
Nó hoạt động (chủ yếu) tốt cho tôi, và tôi có một số cấu trúc thực sự phức tạp. Tôi chưa thử nhưng trong Tùy chọn cho tiện ích mở rộng, nó gợi ý: "Nếu bạn gặp sự cố, bạn có thể có chế độ xem không tuần tự hóa. Bạn có thể tắt tuần tự hóa." Có một hộp kiểm bên dưới thông báo để vô hiệu hóa tính năng này.
Grinn

cực kỳ hữu ích ngay lập tức, ty.
Andrew

37

Xác định một ràng buộc một lần , ở đâu đó trong các tệp thư viện JavaScript của bạn.

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

hơn chỉ đơn giản là sử dụng nó thích điều này:

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

Ưu điểm

  • Sử dụng toàn bộ sức mạnh của trình gỡ lỗi Chrome, như Reveal trong Element Panel
  • Bạn không phải thêm các yếu tố tùy chỉnh vào DOM của mình, chỉ để gỡ lỗi

nhập mô tả hình ảnh ở đây


32

Tôi tìm thấy một cái khác có thể hữu ích. Tôi đã gỡ lỗi một số ràng buộc và thử sử dụng ví dụ Ryans. Tôi đã gặp một lỗi mà JSON tìm thấy một vòng tròn.

<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>

Nhưng, sử dụng phương pháp này, thay thế giá trị liên kết dữ liệu bằng cách sau:

  <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>

Bây giờ nếu tôi nhấp vào phần tử PRE trong khi mở cửa sổ gỡ lỗi chrome, tôi sẽ nhận được một cửa sổ biến phạm vi được lấp đầy độc đáo.

Tìm thấy một cách tốt hơn cho nó:

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

Thực sự hữu ích. Đã gặp phải các vòng lặp loại trực tiếp và các vấn đề đánh dấu dao cạo bằng cách sử dụng <pre data-bind = "text: ko.toJSON ($ data, null, 2)"> </ pre>. <Pre ... debugger> là một cách giải quyết hoàn hảo. Vì một số lý do, các đầu vào RAZOR như @ Html.CheckBox đã phá vỡ ko.toJSON.
Bắc Cực

20

Hướng dẫn từng bước một

  1. Đối với hướng dẫn này, chúng tôi sẽ sử dụng một trong những ví dụ chính thức của KnockoutJS .
  2. Giả sử bạn muốn xem dữ liệu đằng sau liên hệ thứ hai (Sensei Miyagi).
  3. Nhấp chuột phải vào hộp đầu vào đầu tiên của liên hệ thứ hai (hộp có chữ 'Sensei').
  4. Chọn 'Kiểm tra phần tử'. Thanh công cụ dành cho nhà phát triển Chrome sẽ mở.
  5. Mở cửa sổ Bảng điều khiển JavaScript. Bạn có thể truy cập bảng điều khiển bằng cách nhấp vào >=biểu tượng ở góc dưới bên trái của Thanh công cụ dành cho nhà phát triển Chrome hoặc bằng cách mở tab "Bảng điều khiển" trong Thanh công cụ của nhà phát triển Chrome hoặc bằng cách nhấn Ctrl+ Shift+J
  6. Nhập lệnh sau và nhấn Enter: ko.dataFor($0)
  7. Bây giờ bạn sẽ thấy dữ liệu được liên kết với hàng thứ hai. Bạn có thể mở rộng dữ liệu bằng cách nhấn vào tam giác nhỏ bên trái của Object để điều hướng cây đối tượng.
  8. Nhập lệnh sau và nhấn Enter: ko.contextFor($0)
  9. Bây giờ bạn sẽ thấy một đối tượng phức tạp chứa toàn bộ bối cảnh Knockout bao gồm cả root và tất cả các bậc cha mẹ. Điều này hữu ích khi bạn đang viết các biểu thức ràng buộc phức tạp và bạn muốn thử nghiệm với các cấu trúc khác nhau.

Ví dụ đầu ra khi làm theo hướng dẫn ở trên

Ma thuật đen này là gì?

Thủ thuật này là sự kết hợp giữa tính năng $ 0- $ 4 của Chromecác phương thức tiện ích của KnockoutJS . Nói tóm lại, Chrome nhớ mà yếu tố mà bạn đã chọn ở nhà phát triển Chrome Toolbar và phơi bày những yếu tố dưới bí danh $0, $1, $2, $3, $4. Vì vậy, khi bạn nhấp chuột phải vào một phần tử trong trình duyệt của bạn và chọn 'Kiểm tra phần tử', phần tử này tự động trở nên khả dụng dưới bí danh $0. Bạn có thể sử dụng thủ thuật này với KnockoutJS, AngularJS, jQuery hoặc bất kỳ khung JavaScript nào khác.

Mặt khác của mánh khóe là các phương thức tiện ích của KnockoutJS ko.dataFor và ko.contextFor:

  • ko.dataFor(element) - trả về dữ liệu có sẵn để liên kết với phần tử
  • ko.contextFor(element) - trả về toàn bộ bối cảnh ràng buộc có sẵn cho phần tử DOM.

Hãy nhớ rằng, Bảng điều khiển JavaScript của Chrome là một môi trường thời gian chạy JavaScript đầy đủ chức năng. Điều này có nghĩa là bạn không bị giới hạn chỉ nhìn vào các biến. Bạn có thể lưu trữ đầu ra ko.contextForvà thao tác viewmodel trực tiếp từ bàn điều khiển. Hãy thử var root = ko.contextFor($0).$root; root.addContact();và xem những gì xảy ra :-)

Chúc mừng gỡ lỗi!


7

Kiểm tra một điều thực sự đơn giản tôi sử dụng:

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

Hoặc là

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

Sau đó, trong html, bạn đã có:

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

Chỉ cần thay thế nó bằng

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

Nâng cao hơn:

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

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

Thưởng thức :)

CẬP NHẬT

Một điều khó chịu khác là khi bạn đang cố gắng liên kết với một giá trị không xác định. Hãy tưởng tượng trong ví dụ trên rằng đối tượng dữ liệu chỉ là {} chứ không phải {value: 'some text'}. Trong trường hợp này bạn sẽ gặp rắc rối, nhưng với các tinh chỉnh sau, bạn sẽ ổn:

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

5

Tôi đã tạo một dự án github có tên là knockENC.js để giúp trực quan hóa các lỗi này.

https://github.com/JonKragh/knockENC

Nó làm nổi bật các lỗi liên kết và đưa ra một kết xuất của datacontext trên nút đó.

Bạn có thể chơi với một mẫu ở đây: http://htmlpreview.github.io/?https://github.com/JonKragh/knockENC/blob/master/default.htmlm

nhập mô tả hình ảnh ở đây

Tín dụng cho RP Niemeyer cho các mẫu mã Knockout tuyệt vời của anh ấy trên SO để đưa tôi đến điểm này.


3

Cách dễ nhất để xem dữ liệu nào được chuyển đến ràng buộc là thả dữ liệu vào bàn điều khiển:

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

Knockout sẽ đánh giá giá trị cho liên kết văn bản ( thực tế mọi ràng buộc có thể được sử dụng ở đây ) và chuyển dữ liệu $ vào bảng điều khiển trình duyệt.


2

Tất cả các câu trả lời khác sẽ hoạt động tốt, tôi chỉ thêm những gì tôi muốn làm:

Theo quan điểm của bạn (giả sử bạn đã ràng buộc ViewModel):

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

Mã Knockout:

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

Điều này sẽ tạm dừng mã trong trình gỡ lỗi elementvalueAccessor()sẽ chứa thông tin có giá trị.


không cần một ràng buộc tùy chỉnh. Hãy xem stackoverflow.com/documentation/knockout.js/5066/ Kẻ
Adam Wolski

1
Đúng, tôi đồng ý rằng không có nhu cầu nhất định phải làm theo cách này, tôi chỉ muốn chỉ ra rằng đây là một kiểu gỡ lỗi ... mọi người dường như thích làm theo cách riêng của họ :)
Aditya MP

1

Nếu bạn đang phát triển trong Visual studio và IE Tôi thích nó hơn thì data-bind="somebinding:(function(){debugger; return bindvalue; })()"tôi thích nó hơn chức năng echo vì nó sẽ đi đến tập lệnh với tất cả các ràng buộc thay vì tệp eval và bạn chỉ cần nhìn vào dữ liệu $ bối cảnh $ (tôi sử dụng cái này trong Chrome cũng vậy);


Tôi cá là nó không liên quan gì đến Visual Studio hay IE.
Serhiy

@Serhiy Tương tự với chrome nhưng trong chrome Tôi nghĩ bạn có thể truy cập tệp mà không cần. Tôi không nghĩ bạn có thể truy cập tệp trong VS.
Filip Cordas

0

Điều này làm việc cho tôi:

<div data-bind="text: function(){ debugger; }()"></div>
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.