Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Insert an angular js template string inside an element

Tags:

angularjs

Im trying to put some angular js template string inside an element, and expect an complied output. But that's not happening.

HTML

<div ng-controller="testController">     <div ng-bind-html-unsafe="fruitsView"></div> </div> 

Controller:

function filterController($scope){     ...     $scope.arr = ["APPLE", "BANANA"];     $scope.fruitsView = '<div><p ng-repeat="each in arr">{{each}}</p></div>'; } 

The ouput is just {{each}}.

So how do i insert an angular js template string (here $scope.fruitsView) inside an element?

I have made a fiddle for this.

like image 680
Rajkamal Subramanian Avatar asked Feb 13 '13 05:02

Rajkamal Subramanian


People also ask

What is ng-template in angular?

What is ng-Template? The <ng-template> is an Angular element, which contains the template. A template is an HTML snippet. The template does not render itself on DOM.

How do you inject a template in angular?

It basically tells angular to inject the TemplateRef. When we attach our directive to an ng-template, and ask for the TemplateRef in the constructor, the Angular injects the reference to the template enclosed by the ng-template. The Template is inserted into the DOM when the condition is true.

Do I need to include <HTML> and <body> elements in angular templates?

However, because an Angular template is part of an overall webpage, and not the entire page, you don't need to include elements such as <html>, <body>, or <base>, and can focus exclusively on the part of the page you are developing. To eliminate the risk of script injection attacks, Angular does not support the <script> element in templates.

What should I know before learning angular template syntax?

Before learning template syntax, you should be familiar with the following: Each Angular template in your application is a section of HTML to include as a part of the page that the browser displays. An Angular HTML template renders a view, or user interface, in the browser, just like regular HTML, but with a lot more functionality.


1 Answers

In this case, you don't want to just "insert HTML", but compile it. You can create DOM nodes using the $compile service.

var tpl = $compile( '<div><p ng-repeat="each in arr">{{each}}</p></div>' )( scope ); 

As you can see, $compile returns a function that takes a scope object as a parameter, against which the code is evaluated. The resultant content can be inserted into the DOM with element.append(), for example.

Important note: But under no circumstances does any DOM-related code belong in your controller. The proper place is always a directive. This code can easily be thrown into a directive, but I wonder why you are programmatically inserting the HTML at all.

Can you shed some light here so I can provide a more specific answer?

Update

Assuming your data comes from a service:

.factory( 'myDataService', function () {   return function () {     // obviously would be $http     return [ "Apple", "Banana", "Orange" ];   }; }); 

And your template comes from a service

.factory( 'myTplService', function () {   return function () {     // obviously would be $http     return '<div><p ng-repeat="item in items">{{item}}</p></div>';   }; }); 

Then you create a simple directive that reads in the provided template, compiles it, and adds it to the display:

.directive( 'showData', function ( $compile ) {   return {     scope: true,     link: function ( scope, element, attrs ) {       var el;        attrs.$observe( 'template', function ( tpl ) {         if ( angular.isDefined( tpl ) ) {           // compile the provided template against the current scope           el = $compile( tpl )( scope );            // stupid way of emptying the element           element.html("");            // add the template content           element.append( el );         }       });     }   }; }); 

Then from your view:

<div ng-controller="MyCtrl">    <button ng-click="showContent()">Show the Content</button>    <div show-data template="{{template}}"></div> </div> 

And in the controller, you simply tie it together:

.controller( 'MyCtrl', function ( $scope, myDataService, myTplService ) {   $scope.showContent = function () {     $scope.items = myDataService(); // <- should be communicated to directive better     $scope.template = myTplService();   }; }); 

And it should all work together!

PS: this is all assuming your template comes from the server. If it doesn't, then your template should be in the directive, which simplifies things.

like image 173
Josh David Miller Avatar answered Oct 15 '22 03:10

Josh David Miller