2013-12-16 13 views
15

Używam Handlebars (v 1.0.0) do wypełnienia tabeli w HTML. Jednak jakoś to nie wypełnia tabeli, jak jestem przyzwyczajony.Kierownica nie wypełnia tabeli

Oto mój szablon: „Nie znaleziono użytkowników”

{{#if users}} 
<table> 
    {{#each users}} 
     <tr> 
      <td>{{username}}</td> 
      <td>{{email}}</td> 
     </tr> 
    {{/each}} 
</table> 

{{else}} 
    <h3>No users found!</h3> 
{{/if}} 

Więc może znaleźć użytkowników, bo nie widać a kiedy wołam pusty obiekt, pokazuje "Nie znaleziono użytkowników!".

Kiedy nie używam tabeli i wydrukuję tych użytkowników, tak jak w następnym przykładzie. Nazwa użytkownika i adres "pojawią się w moim kodzie HTML.

{{#if users}} 

    {{#each users}} 

     {{username}}<br/> 
     {{email}}<br/> 

    {{/each}} 


{{else}} 
    <h3>No users found!</h3> 
{{/if}} 

Oto jak mój szablon jest zbudowany w javascript:

var htmlSource = $(data).html(); 
var template = Handlebars.compile(htmlSource); 
var compiled = template(usersArray); 
that.$el.html(compiled); 

Teraz kiedy console.log skompilowany obiekt, nie wykazuje już tabelę.

Czy wiesz, dlaczego to nie działa i czy możesz mi pomóc?

EDIT:

Właśnie przetestowałem kilka więcej i okazało się, że dane będą wyświetlane w formacie HTML, kiedy wychodzę na zewnątrz <table> tagi. Jednak <tr> i <td> nie będą wyświetlane w html. Dane w nim zostaną pokazane.

EDYCJA 2: Okazało się, że wydaje się, że problem z jquery lub javascript. Kiedy console.log się htmlSource szablon HTML jest zmieniana tak:

{{#if users}} 

    {{#each users}} 

    {{/each}} 


{{else}} 
<h3>No users found!</h3> 
{{/if}} 

<table><tr> 
    <td>{{username}}</td> 
    <td>{{email}}</td> 
</tr></table> 

Jak widać w tabeli zostanie przeniesiony poza if. Próbowałem innych wersji jquery (2.0.2, 2.0.3, 2.0.1, 1.10.2), ale to nie działało. Próbowałem używać skryptu innerXHTML, ale działa to tak samo jak jQuery.

Zgaduję, że może to być problem FireFox (chociaż próbowałem 25 i 26), Chrome robi to samo ... może coś w EcmaScript?

będzie wam znać wkrótce ...

EDIT 3:

stworzyłem plik HTML z html muszę. Za pomocą skryptu otrzymuję konkretną sekcję html, którą potrzebuję i umieszczam ją w zmiennej danych.

Teraz, gdy konsola rejestruje dane (console.log (dane)), nie ma w tym nic złego. Kiedy konsola loguje dane za pomocą jQuery, zmieniany jest kod HTML: console.log ($ (dane));

Wygląda na to, że coś tam jest nie tak ... ale tylko przy użyciu znaczników tabeli. Czy jest to coś, z czym jQuery nie może sobie poradzić? Nie wiem Wiem, jak przezwyciężyć ten problem za pomocą znacznika script ... Chociaż chciałbym załadować to za pomocą require;)

P.S. nemesv dziękuję za edycję;)

+2

Zakładając, że 'usersArray' wygląda jak' {users: [...]} ', wydaje się działać zgodnie z oczekiwaniami http://jsfiddle.net/nikoshr/Rwg6y/1/ – nikoshr

+0

Jakiej przeglądarki używasz? – MarcoL

+0

Jak dziwne. Używam FireFox 25.0.1, a tablica plików rzeczywiście wygląda tak. Po prostu nie wiem, dlaczego nie działa z tabelą i działa bez .. iw jsfiddle działa poprawnie .. – BonifatiusK

Odpowiedz

14

Upewnij się, że wypisujesz swój szablon w tagu, aby przeglądarka nie próbowała go analizować.

<script type="x-template" id="the-tpl"> 
    {{#if users}} 
     <table> 
      {{#each users}} 
       <tr> 
        <td>{{username}}</td> 
        <td>{{email}}</td> 
       </tr> 
      {{/each}} 
     </table> 
    {{else}} 
     <h3>No users found!</h3> 
    {{/if}} 
</script> 

Jeśli nie ma type atrybut tagu skryptu, parser HTML znajdzie błąd i spróbować go rozwiązać. Z twoich szczegółów błędów, wygląda na to, że tak właśnie jest.

Korzystanie wymagają

Jak można zauważyć załadować używając Wymagaj, niż upewnij się załadować szablonu za pomocą text! plugin: require("text!path/to/template.html")

Aby być jeszcze bardziej wyszukane, można powierzyć całą kompilację Kierownice do A handlebars template loading plugin, więc szablony są prekompilowane wewnątrz twojej kompilacji - prawdopodobnie jest to najlepsze.

Tak czy inaczej, problem polega na tym, że szablon zostanie przeanalizowany przez analizator składni HTML i który narusza zawartość szablonu. Upewnij się, że załadowałeś go jako "tekst" poprzez XMLHttpRequest lub z wymaganym lub wewnątrz tagu skryptowego poprawnie wpisanego.

+0

Cóż, nie używam tagu skryptu do szablonów. Stworzyłem plik html z html, którego potrzebuję. Za pomocą skryptu otrzymuję niezbędną część html i umieszczam ją w danych. Teraz, gdy konsola rejestruje dane (console.log (dane)), nie ma w tym nic złego. Kiedy konsola loguje dane za pomocą jQuery, zmieniany jest kod HTML: console.log ($ (dane)); – BonifatiusK

+1

'$ (dane)' sparsuje twój szablon. Naprawdę nie chcesz, aby twój szablon był analizowany przez silnik HTML. W pytaniu zadałem pytanie o Require.js, więc dodałem w tej odpowiedzi uwagi na ten temat. Ale im bardziej podstawową sprawą jest, aby działała z czymkolwiek, zachowaj swój szablon w HTML-ie przez cały czas, nie może być analizowany i modyfikowany przez analizator składni HTML. –

+0

@BonifatiusK co się dzieje przed tą linią 'var htmlSource = $ (data) .html();' próbujesz uzyskać swój szablon z DOM. oznacza to, że szablon jest już w DOM i parsowany. i jak wskazał Simon. to nie zadziała. jeśli używasz jakiegoś programu ładującego skrypt. wczytaj szablon bezpośrednio w strukturę js. – Mohit

0

Rozwiązanie Simona jest słuszne, a problem jest omawiany w różnych komentarzach. Po prostu umieszczam tutaj kawałki.

jako @rescuecreative zwrócił uwagę, że niektóre przeglądarki usuwają puste tagi <table>, gdy HTML jest wstawiony do DOM.

Ta sprawa jest nieco podobna. Przeglądarki źle się wyświetlają, gdy widzą nieprawidłowy znacznik. ale w tym przypadku nie jest to spowodowane brakiem tabeli tr, td wewnątrz. jego z powodu dodatkowych linii przed tr w tabeli.

Twój problem zaczyna się tutaj.

var htmlSource = $(data).html(); 

niezależnie od używanego mechanizmu ładowania, wstawiając szablon do DOM przed skompilowaniem go za pomocą kierownicy.

Tak dzieje się po dodaniu nieskompilowanego szablonu do DOM.

{{#if users}} <!-- browser does not understand this and tries to print it as it is--> 
<table> <!-- browser sees the table tag and immediately looks for child TR, tbody, thead --> 
    {{#each users}} <!-- but instead finds plain text and hence considers it as invalid markup --> 
     <tr> <!-- the same story is repeated again> 
      <td>{{username}}</td> 
      <td>{{email}}</td> 
     </tr> 
    {{/each}} <!-- such plain strings are taken out of table markup and placed before or after depending upon the browser, in case of chrome placed before the table --> 
</table> 

{{else}} 
    <h3>No users found!</h3> 
{{/if}} 

ten sposób czyni to chrom -

{{#if users}} 
{{#each users}} 
{{/each}} 
<table> 
    <tbody> 
     <tr> 
      <td>{{username}}</td> 
      <td>{{email}}</td> 
     </tr> 
    </tbody> 
</table> 
{{else}} 
    <h3>No users found!</h3> 
{{/if}} 

nie mam firefox ze mną już teraz. ale jestem pewien, że firefox ma własną metodę korekcji znaczników.

po tym, gdy go zabrać z DOM przy użyciu jQuery i skompilować

var htmlSource = $(data).html(); 
var template = Handlebars.compile(htmlSource); 

to po prostu wyjście to

<table> 
    <tbody> 
     <tr> 
      <td>{{username}}</td> 
      <td>{{email}}</td> 
     </tr> 
    </tbody> 
</table> 

jeśli chcesz, możesz zrzucić go po kompilacji, aby zobaczyć.

var compiled = template(usersArray); 
console.log(compiled); 
that.$el.html(compiled); 

To również wyjaśnia, dlaczego otrzymujesz nazwę użytkownika i adres e-mail, gdy usuniesz znacznik tabeli z oryginalnego szablonu.

Teraz, aby rozwiązać ten problem, użyj text plugin, jak wskazał Simon. lub umieść szablon w linii.

ja też użyć requriejs coś po następującym

define([ 
    'underscore', // you can replace this with handlebars 
    'text!path/to/template.html' 
], function(_, Tmpl){ 
    return _.template(Tmpl); //and handlebar pre-compilation here 
}); 

ten sposób można również wymienić ten moduł z prekompilowany szablonu w procesie budowania.

+1

dzięki za podanie przykładu, jak przeglądarka renderuje! – Pascal

+0

proszę podać przyczynę niepoddawania się głosowaniu, aby poprawić sytuację. – Mohit

Powiązane problemy