Making the ng-repeat directive function properly within AngularJS's $interpolate service

While utilizing the AngularJs-UI components for Bootstrap, I encountered an issue with inserting a filled out template into one of the data elements for the popover feature. This seems to work fine for all elements except those inside an ng-repeat loop. How can I make the ng-repeat elements work within an interpolated template?

A plunker showcasing the problem can be found at http://plnkr.co/edit/Cuku7qaUTL1lxRkafKzv. It's not functioning properly because I am not sure how to get Angular-UI-bootstrap to work in Plunker.

<div data-popover="{{createHTML()}}">some content</div>

The local scope includes the function createHTML() which is structured like this:

angular.module('myApp', ['ngSanitize'])
  .controller("myController", function(myService){
    $scope.createHTML = function() {
      var thingy = { blah: "foobar", collection: [ "1", "2", "3" ] };
      return myService.html_for(thingy);
    }
  });

This relies on the following service:

angular.module('myApp')
  .service('myService', function($templateCache, $interpolate, $sanitize, $log) {
    "use strict";

    function html_for(thingy) {
      var template = $templateCache.get('thingyTemplate.html'),
        link = $interpolate(template),
        html = link(thingy),
        unsafe = $sanitize(html);
      return unsafe;
    }

    return {
      html_for: html_for
    }
  });

The templates are as follows:

<script type="text/ng-template" id="thingyTemplate.html">
  <div>
    <div><strong>Blah:</strong> {{blah}}</div>
    <div data-ng-repeat="foo in collection"><strong>Collection:</strong> {{foo}}</div>
    <div><strong>Collection[0]:</strong> {{collection[0]}}</div>
    <div><strong>Collection[1]:</strong> {{collection[1]}}</div>
    <div><strong>Collection[2]:</strong> {{collection[2]}}</div>
  </div>
</script>

<script type="text/ng-template" id="template/popover/popover.html">
<div class="popover {{placement}}" data-ng-class="{ in: isOpen(), fade: animation() }">
  <div class="arrow"></div>

  <div class="popover-inner">
    <h3 class="popover-title" data-ng-bind="title" data-ng-show="title"></h3>
    <div class="popover-content" data-ng-bind-html="content"></div>
  </div>
</div>
</script>

Answer №1

$interpolate doesn't support directives like ngRepeat ( Understanding parse, interpolate, and compile services). $interpolate:

It compiles a string with markup into an interpolation function. This service is utilized by the HTML $compile service for data binding.

If you wish to handle ngRepeat and other directives, you need to utilize $compile. However, using $compile in your scenario will require several changes because:

  • It necessitates a scope to compile against rather than just a context like $interpolate. Additionally, it requires the scope on which thingy resides.

    This implies that properties should be referenced as {{thingy.blah}} instead of {{blah}} inside your template.

  • The compilation needs to occur when the popup is within the DOM.

  • The popup only exists in the DOM when it's open.

Hence, directly substituting $interpolate with $compile inside your service won't suffice.

An alternative approach involves replacing data-ng-bind-html with a directive similar to ng-bind-html but includes a built-in $compile (provided html safety is ensured).

.directive('compile', function($compile) {
  return function(scope, element, attrs) {
    scope.$watch(
      function(scope) {
        return scope.$eval(attrs.compile);
      },
      function(value) {
        var result = element.html(value);
        $compile(element.contents())(scope.$parent.$parent);
      }
    );
  };
});

Usage example (replacing ng-bind-html with compile):

<div class="popover-content" compile="content"></div>

An issue arises as we require thingy to be in scope. There are various ways to address this, but for demonstration purposes, I've manually accessed the scope from which the popover is invoked - hence the use of scope.$parent.$parent.

With this compile directive, there's no longer a need for $interpolate or $sanitize, allowing the function in your service to simply return the appropriate template:

function html_for() {
  var template = $templateCache.get('thingyTemplate.html');
  return template;
}

view demo fiddle

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Having difficulty aligning ListItem to the right within a List

I am working with an array that contains objects which I need to display in ListItems of a List. My goal is to show these ListItems from the array Objects in a layout where odd numbers are on the left and even numbers are on the right. However, I am facing ...

Extracting an ID value from a select box in Vue.js

I'm attempting to extract the value of idTipoExame from the following JSON: { "idTipoExame": "11", "mnemonico": "AUR", "exame": "ACIDO URICO" }, { "idTipoExame": "24&qu ...

Set a breakpoint as soon as the end of a line is identified

I am currently working on a project using React.js and Typescript. Within one of my components, the render looks like this: <div class="test"> Hello dear Sam </div> I am looking for a way to manually instruct the code that if ...

Instructions for installing a script from a browser onto a mobile device and executing it

My proposed plan is as follows - Upon opening a webpage on my mobile browser, I envision the webpage initiating the download and execution of a script on my device. This script could be written in the native language specific to each device (such as Objec ...

The HTML content retrieved through an ajax service call may appear distorted momentarily until the JavaScript and CSS styles are fully applied

When making a service call using ajax and loading an HTML content on my page, the content includes text, external script calls, and CSS. However, upon loading, the HTML appears distorted for a few seconds before the JS and CSS are applied. Is there a sol ...

retrieve data from jsp page using ajax request

I've coded this JSP snippet Map<String, Long> map = new HashMap<String, Long>(); map.put("A", 10L); map.put("B", 20L); map.put("C", 30L); JSONObject json = new JSONObject(); json.accumulate ...

When using Angular 2, the array.splice() function is causing the elements to be removed from the

I am currently working with an HTML table that has default checked rows. <table> <tr> <th></th> <th>Id</th> <th>Name</th> <th>Initial</th> </tr> ...

The exported class does not properly recognize the input values, causing them to be displayed as Undefined and triggering an error

Currently working with Ionic Framework version 6.13.1, I have two services set up in a similar code structure. One is the appointment.service.ts, and the other is the registration.service.ts. Each service corresponds to its own TypeScript file containing a ...

Creating a chat interface with chat bubbles in React JS can be done by implementing components such as Message

Having some JSON data stored in dummyData, I am seeking guidance on how to position chat bubbles on the left and right based on the direction. My framework of choice is Material UI along with the context API. The attached image serves as a visual reference ...

Adding a lone item to an array

One of the functionalities in my component allows users to toggle it on/off by clicking on it: toggleHandler = () => { this.setState({active: !this.state.active}) this.props.getSelection(this.state.active) } render() { const { key, childr ...

Implementing ThreeJS: Deleting an object or mesh from the scene using its UUID

As I work on creating figures and meshes using createFigure(), my goal is to store each uuid in a list where every element includes a button or cross that allows deletion of the object from the scene based on its stored uuid. I am new to three.js and stru ...

Display the iframe once the user clicks on the modal

I am encountering a slow loading issue on a page of my website that contains 60 iframe elements within w3-modals divs. These iframes all load as soon as the page loads, causing significant delays in loading time. Is there a way to optimize the loading of t ...

Having trouble incorporating CSS into a node/express/pug application

I'm currently working on my first Node application using Express and Pug (formerly Jade). Everything seems to be functioning smoothly, except for getting my CSS files to load in the browser. (I keep receiving a "404 Error: GET" when trying to access h ...

jsonwebtoken does not fetch a token

I've been working on a user registration system using nodejs and sequelize. So far, I've successfully implemented the login and register functionalities. However, I am encountering an issue with getting the token after a successful login. Despit ...

"Customizing the error handling in jQuery Ajax using the fail method

I attempted to customize the fail method like shown below, however it ends up triggering both fail methods. As a result, I see 2 alerts: "alert 1" and "override fail". Is there a way to only display the alert "override fail"? var jqxhr = $.ajax("exam ...

Is there any custom fullpagejs code available to implement unique transitions while scrolling through sections?

"I'm in the process of developing a full-page website using fullpage.js. Everything is functioning correctly, but I want to customize the scroll transition similar to the one on this website: ." If you observe the scroll animation on hellomonday, you ...

Oops! There seems to be an error in the code: SyntaxError: DOM Exception 12 setRequestHeader@[

Currently working on the development of a mobile application for Android and IOS using Phonegap, AngularJS, and CORS_REST. Most headers are functioning well on Android, but encountering issues when testing on iPhone with GapDebug. An example of the authen ...

Generating and delivering files without the need to save them to a hard drive

I've been attempting to create a file and send it as a response using expressjs. Here's what I've tried: import { createWriteStream } from 'fs'; const writeStream = createWriteStream('./file.sxcu'); const data = { " ...

Optimizing Static File Caching in Yii

Having a frustrating issue with Yii where my local development environment caches CSS and JS files. Despite making changes to the file, the edits do not reflect in the output and sometimes causes corruption leading to broken functionality. This problem see ...

Tips for determining if a JavaScript cookie has expired

Is it possible to check if a javascript cookie has expired using? I have some conditional tasks to accomplish, and two of those conditions are overlapping. It would be more convenient for me if I could determine if a cookie has expired. Currently, I am u ...