2016-07-27 22 views
0

Ich bin ziemlich neu in Angular, so denke ich, Vorlage ist das falsche Wort. Hier ist was ich meine:Dynamisch laden in Angular Vorlage

Wir haben ein Rails-Backend, das Daten an ein Angular-Frontend liefert. Ich brauche eine ng-repeat, um diese Daten zu zeigen. Das Problem ist, dass die gewünschte Vorlage Teil der Daten ist, die uns von Rails zur Verfügung gestellt werden. Hier ein Beispiel:

JSON serviert von Rails

[ 
    { 
    data: { 
     title: "example title", 
     body: "example body" 
    }, 
    template: "<h1>{{title}}</h1><p>{{body}}</p>" 
    }, 
    { 
    data: { 
     body: "example body two" 
    }, 
    template: "<div>{{body}}</div>" 
    } 
] 

Wir wissen nicht, wie viele Datensätze es wird, was die Vorlagen aussehen wird, oder welche Bindungen sie rufen für (Körper, Titel, Untertitel , etc). Ich kann die Vorlagen nicht lokal speichern, daher müssen alle Daten aus dem Rails-Backend stammen.

Hier ist Pseudo-Code von dem, was Ich mag würde erreichen:

<span ng-repeat="block in blocks"> 
    <template src="block.template" data="block.data"></template> 
</span> 

Diese die angegebene Vorlage verwenden würde und bindet das data Objekt zu.


Noch einmal, ich bin neu zu eckig, also wenn ich klären muss, lass es mich wissen. Vielen Dank!

EDIT: Hier ist mein Versuch einer Richtlinie. Es funktioniert nicht, da anscheinend template keinen Zugriff auf die gewünschte Vorlage hat, die durch block.template dargestellt wird. Dies würde nicht das Binden der Daten abdecken, also müsste ich das einarbeiten, sobald ich die Direktive festgelegt habe.

app.directive("template", function() { 
    return { 
    template: block.template, 
    scope: { 
     block: '=data' 
    }, 
    restrict: 'E' 
    }; 
}); 

EDIT 2:

Hier ist ein weiterer Versuch, das nicht funktioniert. Dieser zeigt die Vorlage auf dem Bildschirm, sondern in der Konsole es Fehler, die scope.$watch is not a function

app.directive('template', function ($compile) { 
    return { 
    restrict: 'A', 
    replace: true, 
    scope: { 
     tmpl: '=template' 
    }, 
    link: function postLink(scope, element, attrs) { 
     scope.$watch('tmpl', function (block) { 
     element.html(block.template.blank_template); 
     $compile(element.contents())(block.payload); 
     }); 
    } 
    }; 
}); 
+0

Vielleicht die Verwendung von [** ngBindHtml **] (https://docs.angularjs.org/ api/ng/directive/ngBindHtml) wäre in diesem Fall nützlich. – developer033

+0

@ developer033 Ich habe das probiert, aber es hat die Bindings wörtlich interpretiert, also hieß es '{{title}}' auf der Seite anstelle der gewünschten Daten –

+0

Try * Direktiven * dann – developer033

Antwort

0

Sie können es mit einer Richtlinie tun:

im Grunde etwas entlang der Linien von

//Assuming App is your Angular App Instance and Angular at least 1.4ish 
app.directive('template',['$compile', function($c) { 
     return { 
     link: function (scope, el, attrs, controller) { 
      el.html(scope.template); 
      $c(el.contents())(scope); 
     }, 
     scope: { 
      template: "=tpl", 
      data: "=data" 
     } 
     } 
}); 

Sie dann kann es so verwenden:

<span ng-repeat="block in blocks"> 
    <template tpl="block.template" data="block.data"></template> 
</span> 
+0

Ich garantiere nicht, dass es 100% fehlerfrei ist, aber es sollte Ihnen eine Idee geben ... – MiltoxBeyond

+0

Vielen Dank! Es scheint nicht zu funktionieren, aber ich werde herumspielen und sehen, was ich tun kann. Frage: Im Scope-Objekt schreiben Sie 'data:" = data "', aber 'data' wird nirgends verwendet. Nimmt Angular das automatisch an? –

+0

Daten werden an das Scope-Objekt dieser Instanz übergeben, sodass es an die Vorlage für die Bindung weitergeleitet wird. Um diese Werte zu referenzieren, müssen Sie wie folgt referenzieren: '{{data.title}}' usw. – MiltoxBeyond