KnockoutJS için şablon bağlama hataları nasıl ayıklanır?


199

KnockoutJS şablonlarında hata ayıklama sorunları ile sorun yaşamaya devam ediyorum.

Diyelim ki " items" adlı bir özelliğe bağlamak istiyorum ama şablonda bir yazım hatası yapıyorum ve (mevcut olmayan) özelliğe " item" bağlanıyor .

Chrome hata ayıklayıcısını kullanmak yalnızca şunu söyler:

"item" is not defined.

Bağlama sorunu hakkında daha fazla bilgi edinmeme yardımcı olan araçlar, teknikler veya kodlama stilleri var mı?

Yanıtlar:


344

Belirli bir kapsamda hangi verilerin mevcut olduğu ile ilgili bir sorun olduğunda oldukça sık yaptığım bir şey, şablonu / bölümü aşağıdaki gibi bir şeyle değiştirmektir:

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

Veya biraz daha okunabilir bir sürüm istiyorsanız:

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

Bu, o kapsamda bağlanan verileri tükürecek ve işleri uygun şekilde iç içe yerleştirdiğinizden emin olmanızı sağlayacaktır.

Güncelleme: KO 2.1'den itibaren , aşağıdakileri basitleştirebilirsiniz:

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

Şimdi argümanlar aktarılıyor JSON.stringify.


ohh. Bu soruyu da sormam gerekiyor. Console.log verilerine karmaşık kod parçası kullanıldı. Şimdi çok daha kolay.
AlfeG

3
Hata ayıklama ipuçları hakkında daha fazla düşünmek ve belki bir blog yazısı yapmak zorundayım. Akla gelen başka bir şey, değerlerin değişmesini izlemek için gözlemlenebilir veya hesaplanmış gözlemlenebilirlere karşı manuel abonelikler yapmaktır. Sanki namegözlenebilir bir şey yapıyorname.subscribe(function(newValue) { console.log("name", newValue); });
RP Niemeyer

1
Bu yanıt nispeten eski olduğu için olabilir, ancak neden console.log'u kullanmıyorsunuz ve nesne özelliklerini görüntülemek için hata ayıklayıcının tüm gücünü kullanmıyor musunuz? Bkz. Örneğin: stackoverflow.com/a/16242988/647845
Dirk Boer

1
@DirkBoer - console.log kullanmak da harika bir yol olabilir. Çoğu zaman bir foreachsenaryoda olduğu gibi öğelerimin yanındaki verileri görmek istiyorum ve ilgili işlenmiş biçimlendirme içindeki sayfada konsolu gözden geçirmekten daha kolay görüyorum. Sadece duruma bağlı. Burada daha fazla düşüncelerim var: knockmeout.net/2013/06/… . Ayrıca, bağlanma gibi "temiz" bir sürümünü günlüğe kaydetmek isteyebilirsiniz console.log(ko.toJS(valueAccessor()).
RP Niemeyer

1
@RuneJeppesen - Ne tür veriler serileştirdiğinizden emin değilim, ancak böyle bir şey yardımcı olabilir: knockmeout.net/2011/04/…
RP Niemeyer

60

Chrome'u geliştirme için kullanıyorsanız , bağlama araçlarını doğrudan Geliştirici Araçları Öğeleri panelinde gösteren, Knockoutjs bağlam hata ayıklayıcısı adı verilen gerçekten harika bir uzantı (bağlı olmadığım) var .


3
Keşke Firefox veya Firebug buna sahip olsaydı. Böyle bir şey bilen var mı?
Patrick Szalapski

Görünüşe göre destek düşürüldü. Karmaşık bir veri bağlama yapısı kullanırsanız kromun çökmesine neden olur. Yaklaşık bir yıldır hiçbir projemde çalışmadı.
Arctic

Duyduğuma üzüldüm, ama uzun zamandır KO'dan Ember'e geçtim.
neverfox

1
Benim için (çoğunlukla) iyi çalışıyor ve gerçekten karmaşık yapılarım var. Ben denemedim ama uzantı seçenekleri için, "Eğer çökme yaşarsanız muhtemelen serileştirilemez bir viewmodel var. Serileştirmeyi kapatabilirsiniz." Bu özelliği devre dışı bırakmak için iletinin altında bir onay kutusu bulunur.
Grinn

anında çok faydalı, ty.
Andrew

37

JavaScript kitaplık dosyalarınızda bir yerde bir bağlamaHandler tanımlayın .

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

sadece kullanmaktan hoşlanır:

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

Avantajları

  • Elements Panelinde Göster gibi Chrome hata ayıklayıcısının tam gücünü kullanın
  • DOM'nize yalnızca hata ayıklamak için özel öğeler eklemek zorunda değilsiniz

resim açıklamasını buraya girin


32

Yararlı olabilecek başka bir tane buldum. Bazı ciltlemeler hata ayıklama ve Ryans örnek kullanmayı denedim. JSON dairesel bir döngü bulduğunda bir hata aldım.

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

Ancak, bu yaklaşımı kullanarak veri bağlama değeri aşağıdakilerle değiştirildi:

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

Şimdi krom hata ayıklama penceresi açıkken PRE öğesini tıklarsam, güzel doldurulmuş bir kapsam değişkenleri penceresi alırım.

Bunun için biraz daha iyi bir yol buldum:

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

Gerçekten kullanışlı. <Pre data-bind = "text: ko.toJSON ($ data, null, 2)"> </pre> kullanarak nakavt dairesel döngüler ve Razor biçimlendirme sorunlarıyla karşılaşıyordum. <Pre ... debugger> mükemmel bir çözümdür. Nedense @ Html.CheckBox gibi RAZOR girdileri ko.toJSON'u bozuyordu.
Arctic

20

Adım adım rehber

  1. Bu kılavuz için resmi KnockoutJS örneklerinden birini kullanacağız .
  2. İkinci kişinin (Sensei Miyagi) arkasındaki verileri görmek istediğinizi varsayalım.
  3. İkinci kişinin ('Sensei' metnine sahip) ilk giriş kutusuna sağ tıklayın.
  4. 'Elemanı incele'yi seçin. Chrome Geliştirici Araç Çubuğu açılır.
  5. JavaScript Konsolu penceresini açın. Konsola >=, Chrome Geliştirici Araç Çubuğu'nun sol alt tarafındaki simgeyi tıklayarak veya Chrome Geliştirici Araç Çubuğu'ndaki "Konsol" sekmesini açarak veya Ctrl+ Shift+ tuşlarına basarak erişebilirsiniz.J
  6. Aşağıdaki komutu yazın ve Enter tuşuna basın: ko.dataFor($0)
  7. Şimdi ikinci satıra bağlı verileri görmelisiniz. Nesne ağacında gezinmek için Nesnenin solundaki küçük üçgene basarak verileri genişletebilirsiniz.
  8. Aşağıdaki komutu yazın ve Enter tuşuna basın: ko.contextFor($0)
  9. Artık kök ve tüm ebeveynler dahil olmak üzere tüm Nakavt bağlamını içeren karmaşık bir nesne görmelisiniz. Bu, karmaşık bağlayıcı ifadeler yazarken ve farklı yapıları denemek istediğinizde kullanışlıdır.

Yukarıdaki kılavuzu takip ederken örnek çıktı

Bu kara büyü nedir?

Bu hile, Chrome'un 0-4 $ arası özelliği ve KnockoutJS'nin yardımcı yöntemlerinin bir kombinasyonudur . Kısacası, Krom Chrome Geliştirici Araç Çubuğu seçtiğiniz hangi unsurlar hatırlar ve takma altında bu öğeleri ortaya $0, $1, $2, $3, $4. Dolayısıyla, tarayıcınızdaki bir öğeye sağ tıklayıp 'Öğeyi incele' seçeneğini belirlediğinizde, bu öğe otomatik olarak takma ad altında kullanılabilir hale gelir $0. Bu numarayı KnockoutJS, AngularJS, jQuery veya başka herhangi bir JavaScript çerçevesi ile kullanabilirsiniz.

Hilenin diğer tarafı KnockoutJS'nin ko.dataFor ve ko.contextFor yardımcı yöntemleri:

  • ko.dataFor(element) - öğeye bağlanmak için mevcut olan verileri döndürür
  • ko.contextFor(element) - DOM öğesi tarafından kullanılabilen tüm bağlama bağlamını döndürür.

Unutmayın, Chrome'un JavaScript Konsolu tamamen işlevsel bir JavaScript çalışma zamanı ortamıdır. Bu, yalnızca değişkenlere bakmakla sınırlı olmadığınız anlamına gelir. ko.contextForViewmodelin çıktısını depolayabilir ve doğrudan konsoldan değiştirebilirsiniz. Deneyin var root = ko.contextFor($0).$root; root.addContact();ve neler olduğunu görün :-)

Mutlu hata ayıklama!


7

Kullandığım gerçekten basit bir şeye göz atın :

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

Veya

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

Sonra html'de, diyelim ki:

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

Sadece yerine

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

Daha ileri:

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

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

Zevk almak :)

GÜNCELLEME

Bir başka can sıkıcı şey, tanımlanmamış bir değere bağlanmaya çalıştığınızda. Yukarıdaki örnekte veri nesnesinin sadece {} değil {değer: 'bazı metinler "} olduğunu düşünün. Bu durumda başınız belada olacak, ancak aşağıdaki tweak ile iyi olacaksınız:

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


3

Hangi verilerin ciltlemeye aktarıldığını görmenin en kolay yolu , verileri konsola bırakmaktır:

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

Nakavt, metin ciltleme değerini değerlendirir ( burada herhangi bir ciltleme kullanılabilir ) ve konsol tarayıcı paneline $ verilerini temizler.


2

Diğer tüm cevaplar harika olacak, sadece yapmak istediğimi ekliyorum:

Görüşünüze göre (zaten bir ViewModel bağladığınızı varsayarsak):

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

Nakavt kodu:

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

Bu, hata ayıklayıcıdaki kodu duraklatacak elementve valueAccessor()değerli bilgiler içerecektir.


özel bir ciltlemeye gerek yoktur. Bir göz atın stackoverflow.com/documentation/knockout.js/5066/...
Adam Wolski

1
Evet, bu şekilde yapmak için kesin bir ihtiyaç olmadığını kabul ediyorum, sadece bunun bir hata ayıklama stili olduğunu belirtmek istedim ... herkes bunu kendi tarzında yapmaktan hoşlanıyor gibi görünüyor :)
Aditya MP

1

Visual studio ve IE geliştiriyorsanız data-bind="somebinding:(function(){debugger; return bindvalue; })()"ben bunu daha çok daha sonra yankı fonksiyonu gibi tüm bağlamalar ile senaryoya gidecek çünkü eval dosyası ve sadece $ context $ verilere (ben kullanmak bunu Chrome'da da);


Bahse girerim Visual Studio veya IE ile ilgisi yoktur.
Serhiy

@Serhiy Krom ile aynı, ancak krom dosya olmadan dosyaya erişebileceğini düşünüyorum VS dosyaya erişebilirsiniz sanmıyorum.
Filip Cordas

0

Bu benim için çalışıyor:

<div data-bind="text: function(){ debugger; }()"></div>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.