2017-01-07 5 views
1

Ich habe Anwendungsfall wie unten, wo ich die innerHTML wie folgt bevölkern. Jetzt das Problem ist, ich möchte das Template-Literal im Kontext von Forloop auflösen. Irgendwelche Hinweise ?Auflösen von Vorlagenliteralen in einem späteren Kontext

var blog_entries_dom = 'blog_entries'; 
var blog_entries = [ 
    { 
     "title": "Hello World", 
     "id": 2, 
     "body": "<p>Hello World</p>" 
    }, 
    { 
     "title": "World Hello", 
     "id": 3, 
     "body": "<p>World Hello</p>" 
    } 
]; 

var blog_entry_template = `<div class="post-preview"> 
         <a href="post.html"> 
          <h2 class="post-title"> 
           ${item.title} 
          </h2> 
          <h3 class="post-subtitle"> 
           ${item.body} 
          </h3> 
         </a> 
         <p class="post-meta">Posted by <a href="#">Start Bootstrap</a> #Created At </p> 
        </div> 
        <hr>`; 


var populate_children = function (element_id, objects_list, template) { 

    var element = document.getElementById(element_id); 

    var html = ''; 

    for (var i = 0; i < list.length; i++) { 
     var item = list[i] 
     html += template; 
    } 

    element.innerHTML = html; 
}; 

populate_children (blog_entries_dom, blog_entries, blog_entry_template);

enter image description here

+0

Was wäre der empfohlene Weg, dies zu erreichen? Ich habe eine Vorlage und eine Liste von Objekten zur Hand und ich muss sie nähen. – nehemiah

Antwort

1

Template Literale sind genau das: Literale. Sie werden wie alle Literale an der Stelle ausgewertet, an der sie erscheinen. Sie sind keine Objekte, Sie können sie nicht weitergeben.

Stattdessen können Sie sie in eine Funktion einfügen und die Funktion übergeben. Lassen Sie die Funktion die Dinge akzeptieren, die die Vorlage benötigt, und geben Sie das Ergebnis der Auswertung zurück.

In Ihrem Fall Sie nur blog_entry_template Funktion in einem Pfeil, und nennen es:

var blog_entries_dom = 'blog_entries'; 
var blog_entries = [ 
    { 
     "title": "Hello World", 
     "id": 2, 
     "body": "<p>Hello World</p>" 
    }, 
    { 
     "title": "World Hello", 
     "id": 3, 
     "body": "<p>World Hello</p>" 
    } 
]; 

var blog_entry_template = item => `<div class="post-preview"> 
    <a href="post.html"> 
     <h2 class="post-title"> 
      ${item.title} 
     </h2> 
     <h3 class="post-subtitle"> 
      ${item.body} 
     </h3> 
    </a> 
    <p class="post-meta">Posted by <a href="#">Start Bootstrap</a> #Created At </p> 
</div> 
<hr>`; 


var populate_children = function (element_id, objects_list, template) { 

    var element = document.getElementById(element_id); 

    var html = ''; 

    for (var i = 0; i < list.length; i++) { 
     html += template(list[i]); 
    } 

    element.innerHTML = html; 
}; 

Verbrauch:

populate_children("some-id", blog_entries, blog_entry_template); 
+0

* (Doh! Editing Fehler, wenn Sie 'var formatItem = ...' da irgendwo sehen, klicken Sie auf Aktualisieren.) * –

+0

Also wie behalte ich die Vorlage außerhalb dieser Methode? Weil diese Methode generisch ist und das Template-Literal als Parameter akzeptiert. – nehemiah

+0

@itsneo: Das ist nicht was in deiner Frage ist. Die Antwort lautet: Vorlagenliterale sind genau das: Literale. Sie sind keine Objekte, Sie können sie nicht weitergeben. Was Sie stattdessen tun können, setzen Sie sie in eine Funktion und übergeben Sie die Funktion herum. Sie haben die Funktion, die Dinge, die die Vorlage benötigt, zu akzeptieren und das Ergebnis der Auswertung zurückzugeben. –

1

ich andere Lösung habe, könnte den Prototyp mit einer guten Idee, !

String.prototype.replaceTemp = function(replaceObj) { 
    return this.replace(/{\$(\w{1,20})}/g, function(matchStr, agr) { 
    if (replaceObj[agr] instanceof Object || replaceObj[agr] instanceof Function) { 
     var _tempPool = (window.TEMP_POOL = window.TEMP_POOL || []); 
     var _length = _tempPool.length; 
     _tempPool[_length] = replaceObj[agr]; 

     if (replaceObj[agr] instanceof Function) 
     return "TEMP_POOL[" + _length + "](this);" 
     else 
     return "TEMP_POOL[" + _length + "]"; 

    } else { 
     return replaceObj[agr] || ""; 
    } 

    }); 
}; 


    var blog_entries_dom = 'blog_entries'; 
    var blog_entries = [ 
     { 
      "title": "Hello World", 
      "id": 2, 
      "body": "<p>Hello World</p>" 
     }, 
     { 
      "title": "World Hello", 
      "id": 3, 
      "body": "<p>World Hello</p>" 
     } 
    ]; 

    var blog_entry_template = `<div class="post-preview"> 
          <a href="post.html"> 
           <h2 class="post-title"> 
            {$title} 
           </h2> 
           <h3 class="post-subtitle"> 
            {$body} 
           </h3> 
          </a> 
          <p class="post-meta">Posted by <a href="#">Start Bootstrap</a> #Created At </p> 
         </div> 
         <hr>`; 


    var populate_children = function (element_id, objects_list, template) { 

     var element = document.getElementById(element_id); 

     var html = ''; 

     for (var i = 0; i < list.length; i++) { 
      html += template.replaceTemp(list[i]); 
     } 

     element.innerHTML = html; 
    }; 
+0

Nein, die Erweiterung der eingebauten Prototypen wird nicht als gute Idee betrachtet. Und dieser globale 'TEMP_POOL' ist sicherlich ein schlechter. – Bergi

+0

Build-in-Prototyp wird einfach zu bedienen, und globale 'TEMP_POOL' für Bindungsereignis, andernfalls müssen Sie zunächst DOM-Element dann Binding-Ereignis erstellen, aber es einfach nur Variablen in Vorlage ersetzen. – Draco

Verwandte Themen