Dynamically transcluding multiple elements in Angular

Angular 1.5 introduces the option to multi-transclude.

An interesting feature would be the ability to transclude a variable number of items into a directive and specify their names and positions at a later stage (for example, in the link/compile functions).

For instance, I envision being able to achieve something like:

//Demonstration of directive usage
<multi-slot-transclude-example>
<transclude1>TEST1</div>
<transclude2>TEST2</div>
<transclude3>TEST3</div>
<transclude4>TEST4</div>
.... any number of dynamic items ...
</multi-slot-transclude-example>

//Sample directive that dynamically transcludes multiple items
angular.module("multiSlotTranscludeExample", [])
    .directive("directiveName", function(){
    return {
        restrict: 'E',
        transclude: {
            't1': '?transclude1',
            't2': '?transclude2',
            //I want this list to be capable of dynamic definition (e.g., in the link function)
        },
        template: '<div ng-repeat="n in transcludedElementList">'
        + '<div ng-transclude="t{{n}"></div>'
        + '</div>'
        };
})

It's worth mentioning that when implementing a multi-transclude in a directive, you need to know beforehand the number of items to be transcluded.

Is there a way to achieve a similar functionality either through the link function or using a workaround while maintaining the current transclusion capabilities?

Answer №1

It appears that Angular lacks a simple method to achieve this without being intrusive.

Nevertheless, with a minor adjustment, it is possible to make it work.

The key is to modify the transclusion slot logic within angular.js:

...

var slots = createMap();

$template = jqLite(jqLiteClone(compileNode)).contents();

// A small change for dynamic transclusion capability
if (directiveValue === 'dynamic') {
  directiveValue = $parse(templateAttrs.transcludeDynamic)();
}

if (isObject(directiveValue)) {

  // If there are transclusion slots,
  // gather them, compile them, and save their transclusion functions
  $template = [];

...

By doing this, we can define the transclusion options in the consumer of the component like this:

<my-custom-component transclude-dynamic="{testSlot: 'test', testSlot2: 'test2'}">
  <test>something to transclude</test>
  <test2>then another slot content to transclude</test2>
</my-custom-component>

In the component, we activate dynamic transclusion:

...
selector: 'myCustomComponent',
template: template,
transclude: 'dynamic',
bindings: {
  transcludeDynamic: '<'
}

It's important to note that we also bind the transclusion information, allowing us to use ng-repeat, ng-if, and other directives on it.

For instance:

<div ng-repeat="(slot, name) in $ctrl.transcludeDynamic">
  <div ng-transclude="{{slot}}"></div>
  <hr>
  <div>something else</div>
</div>

PR: https://github.com/angular/angular.js/pull/14227

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

Tips for managing asynchronous REST errors in unit tests with Jest

Below is the code snippet for my Node.js test file. This unit test case is failing, here are the details of the code and error message: jest.unmock('./utils.js'); describe('test', () => { it('test', async (done) => ...

Acquiring information from a variable via an HTTP request

I am new to making http requests and using PHP. I have a code snippet that makes an AJAX call: xmlhttp.onreadystatechange = function() { if (this.readyState == 4 && this.status == 200) { var doc = xmlhttp.response; myFunc( ...

Creating Angular components in *ngFor loop

I have set up multiple radio button groups by dynamically populating options using ngFor within a ngFor loop. categories:string[] = [category_1, ..., category_n]; options:string[] = [option_1, ..., option_n]; <fluent-radio-group *ngFor='let ca ...

Ways to update a single column in an HTML table when there is a change

I'm stuck trying to find a more efficient method for updating a column in an html table without having to reload the entire table. The table consists of player stats, all pulled from my MYSQL database and displayed in the table except for the last col ...

Cookie parsing functionality in Node JS malfunctioning

Currently, I am working through a tutorial on cookie management in Express JS found at . The goal is to implement cookies in my web application to authenticate requests to an API that I am constructing with Node JS. To set the cookie upon user login, I emp ...

Tips for stopping webpack from creating compiled files in the source directory

I'm in the process of transitioning my AngularJs project from ES6 to TypeScript and I've integrated webpack with ts-loader. However, I've encountered an issue where the compiled files and source maps are saved in my directory instead of bei ...

JS: I'm struggling to understand the scope

I've been working on adapting CouchDB's JS API to function asynchronously, but I'm encountering an unresolved error: You can find my version of the JS API here on Pastebin. Whenever I execute (new CouchDB("dbname")).allDocs(function(result) ...

Ensuring the integrity of ASP.NET Webforms using AngularJS

When using AngularJS validation status, I am faced with the issue of needing to reference the form by its name. However, the current form does not have a name, and I am unsure of how to set one without resorting to using JavaScript, which is not my preferr ...

What could be causing my JavaScript code to not function properly in an HTML document?

Hello, I am a beginner in the world of coding and currently delving into web development. Recently, I was following a tutorial on creating a hamburger menu but I seem to be encountering some issues with the JavaScript code. I have double-checked my Visual ...

Issue with function operation

Incorporating HTML code with Angular elements on the homepage of a PHP forum script has been challenging. I have inserted the PHP code into index.template.php as instructed, but unfortunately, nothing is being displayed. <?php /** * This function ...

Dynamic updating of scores using Ajax from user input

My goal is to design a form that includes three "Likert Scale" input fields. Each of these three inputs will have a total of 10 points that can be distributed among them. The submit button should become enabled when the score reaches 0, allowing users to s ...

What could be the reason for my user input not being captured and saved as variable data on the HTML webpage?

Here is the code I am working with: var g = document.getElementById("al").value; function start() { document.getElementById("test2").innerHTML = typeof(g) + parseFloat(g); } <p id="test2">Output will be displayed here:</p> <form> ...

Each time a new client connects, socket.io replicates the information

Exploring Node.js and socket.io for the first time, I have developed a small application where a table is meant to be displayed in real-time via socket.io when a function is triggered through a websocket (function triggers an "emit"). However, I'm fac ...

Tips for improving the loading speed of a table during scrolling with JavaScript

Is there a way to speed up the loading time of a <table> with 20000 rows? As I scroll through the page, it feels very sluggish and takes around 4-5 seconds to load the remaining table data. I'm unsure how to tackle this issue, which is why I h ...

The mesmerizing world of Vue templates and transition groups

My previous simple list had transitions working perfectly, but now that I am using components and templates the transitions no longer work. Can anyone help me understand why? I want each item to animate individually, but it seems like all items are transi ...

The struggle of accessing child components using ViewChild in Angular

I am facing an issue with a dialog box that is supposed to display a child component separately. Below is the code for the child component: @Component({ selector: 'userEdit', templateUrl: './edituser.component.html', styleUrls: [ ...

Looking to verify a disabled select element and adjust the opacity of that element when it is disabled

$_product = $this->getProduct(); $_attributes = Mage::helper('core')->decorateArray($this->getAllowAttributes()); ?> <?php if ($_product->isSaleable() && count($_attributes)):?> <dl> <?php foreach($_attrib ...

Adjust the placement of the fixed header waypoint or change its offset

Currently working on developing a Wordpress site with the Avada theme, my goal is to have a sticky header that starts immediately at the top of the page. This is the website in progress: The site I'm trying to emulate is synergymaids.com. If you vi ...

What causes the Request.Params of IHttpHandler to be accurate on the initial call, but become null on the subsequent call?

My HTML/Javascript page utilizes a jQuery ajax call to communicate with a .NET ajax handler (.ASHX). The issue arises in subsequent calls where the parameters passed in the data object are unexpectedly NULL despite being correct during the first call. Her ...

Unable to access Bootstrap dropdown menu after initial ajax form submission

I am encountering an issue with a dropdown menu on my webpage, specifically within the manager.php file. Please excuse any formatting discrepancies as I am using Bootstrap: <!-- Bootstrap --> <script type="text/javascript" src="https://netdna ...