Handlebars.js analysiert Objekt anstelle von [Objektobjekt]

74

Ich verwende Lenkervorlagen und JSON-Daten sind bereits in [Objektobjekt] dargestellt. Wie analysiere ich diese Daten außerhalb der Lenker? Ich versuche beispielsweise, eine JavaScript-Variable auf der Seite über ein Lenker-Tag zu füllen, aber das funktioniert nicht.

Irgendwelche Vorschläge? Vielen Dank!

BEARBEITEN:

Zur Verdeutlichung verwende ich ExpressJS mit Lenker für Vorlagen. Auf meiner Route habe ich Folgendes:

var user = {}
user = {'id' : 123, 'name' : 'First Name'}

res.render('index', {user : user});

Dann habe ich in meiner index.hbs-Vorlage jetzt ein {{user}}Objekt. Ich kann {{#each}}das Objekt gut durchlaufen. Ich verwende jedoch auch Backbonejs und möchte diese Daten an eine Ansicht wie die folgende übergeben:

myView = new myView({user : {{user}});

Das Problem ist, dass es {{user}}einfach [Object object]in der Quelle angezeigt wird, wenn ich es in console.log einfüge. Ich erhalte die Fehlermeldung "Unerwarteter Bezeichner".

dzm
quelle
Sie müssen näher auf "funktioniert nicht" eingehen. Können Sie einen relevanten Codeausschnitt und eine Beschreibung dessen bereitstellen, was Sie erwarten, anstatt [Object object]? Wenn Sie lediglich versuchen, die Schlüssel / Werte des Objekts anzuzeigen, sollten Sie sie console.logmit einem Debugger oder verwenden JSON.stringify.
Jonathan Lonowski
Console.log zeigt auch [Objekt Objekt]. Ich werde den Beitrag aktualisieren, um ihn besser zu erklären.
dzm

Antworten:

168

Bei der Ausgabe {{user}}ruft der Lenker zuerst den Wert des user'ab .toString(). Für einfache Objects ist das Standardergebnis das, was"[object Object]" Sie sehen.

Um etwas Nützlicheres zu erhalten, möchten Sie entweder eine bestimmte Eigenschaft des Objekts anzeigen:

{{user.id}}
{{user.name}}

Oder Sie können einen Helfer verwenden / definieren, um das Objekt anders zu formatieren:

Handlebars.registerHelper('json', function(context) {
    return JSON.stringify(context);
});
myView = new myView({
    user : {{{json user}}} // note triple brackets to disable HTML encoding
});
Jonathan Lonowski
quelle
12
es sollte sein: {{{json user}}}, sonst wird die json-Zeichenfolge codiert.
Jim Liu
Danke, das ist perfekt. Für Expressbenutzer:app.set('view engine', 'hbs'); var Handlebars = require('hbs');
Oneiros
4
Funktioniert super. Auch für Express-Lenker- Benutzer:var exphbs = require('express-handlebars'); app.engine('handlebars', exphbs({ helpers: { json: function (context) { return JSON.stringify(context); } } }));
JayChase
4
Oder schließen Sie beim Rendern einfach die Helfer ein. res.render('index', { var1: 'some value', helpers: { json: function (context) { return JSON.stringify(context); } });
Derek Soike
1
@acmoune Beim Überqueren des Netzwerks vom Server zum Client muss das Objekt in ein Datenformat serialisiert werden. Es ist also nicht unbedingt möglich, es so zu senden, wie es im Speicher ist. Möglicherweise können Sie jedoch die Definition des UserTyps freigeben und die Instanz für den Client rekonstruieren user : new User({{{json user}}}).
Jonathan Lonowski
13

Sie können den JSON einfach stringifizieren :

var user = {}
user = {'id' : 123, 'name' : 'First Name'};
// for print
user.stringify = JSON.stringify(user);

Dann im Vorlagendruck von:

{{{user.stringify}}};
nguyên
quelle
1
Die obigen Antworten sind großartig. Ich traf tatsächlich ein Problem , wenn sie in der Ansicht , die die JSON - String - Rendering , weil ich ein Unescaped Zitat hatte, löste diese Antwort , dass stackoverflow.com/a/22105906/7998284
hazelcodes
4

Ich verwende serverseitiges Template in Node-Js, aber dies kann auch clientseitig gelten. Ich registriere Jonathans Json-Helfer im Knoten. In meinem Handler füge ich über res.locals Kontext (z. B. Adressbuch) hinzu. Dann kann ich die Kontextvariable clientseitig wie folgt speichern:

<script>
  {{#if addressBook}}
  console.log("addressBook:", {{{json addressBook}}});
  window.addressBook = {{{json addressBook}}};
  {{/if}}
</script>

Beachten Sie die dreifachen Locken (wie von Jim Liu hervorgehoben ).

Jeff Lowery
quelle
1

Sie versuchen, die Template-Syntax {{ }}in einem ungültigen JSON-Objekt zu übergeben.

Möglicherweise müssen Sie stattdessen Folgendes tun:

myView = new myView({ user : user });

Terry
quelle
0

Wenn Sie mehr Kontrolle über die Ausgabeformatierung wünschen, können Sie Ihren eigenen Helfer schreiben. Dieser hat eine rekursive Funktion zum Durchlaufen verschachtelter Objekte.

  Handlebars.registerHelper('objToList', function(context) {
    function toList(obj, indent) {
      var res=""
      for (var k in obj) { 
          if (obj[k] instanceof Object) {
              res=res+k+"\n"+toList(obj[k], ("   " + indent)) ;
          }
          else{
              res=res+indent+k+" : "+obj[k]+"\n";
          }
      }
      return res;
    }    
    return toList(context,"");
  });

Wir haben Lenker für E-Mail-Vorlagen verwendet. Dies hat sich für einen Benutzer wie den folgenden als nützlich erwiesen

{
  "user": {
    "id": 123,
    "name": "First Name",
    "account": {
      "bank": "Wells Fargo",
      "sort code": " 123-456"
    }
  }
}
Phil C.
quelle