Developing components and injecting them dynamically in Angular 2 using Typescript remotely

I am currently exploring the potential of Angular 2 as a foundational technology for a flexible administration dashboard, emphasizing the need for extensibility and customization. I envision an environment where external developers can create their own components and seamlessly integrate them into my pre-existing framework without needing access to the underlying source code. This would allow developers to focus solely on developing the necessary resources for their components (.html, .ts/.js files) without being burdened by the complexities of the main application structure. These components could then be served statically through servlets or other means. Is this concept even theoretically possible? Could I establish a "main" app module capable of dynamically importing, declaring, and understanding typescript-based components from a predefined location?

Answer №1

Yes, I found a helpful example at this link.

It was by chance that I came across this specific example while browsing the Plunkr homepage.

An interesting concept is passing components as object parameters to a function for compilation.

import {Compiler, Component, NgModule, OnInit, ViewChild,
  ViewContainerRef} from '@angular/core'
import {BrowserModule} from '@angular/platform-browser'

@Component({
  selector: 'my-app',
  template: `<h1>Dynamic template:</h1>
             <div #container></div>`
})
export class App implements OnInit {
  @ViewChild('container', { read: ViewContainerRef }) container: ViewContainerRef;

  constructor(private compiler: Compiler) {}

  ngOnInit() {
    this.addComponent(
      `<h4 (click)="increaseCounter()">
         Click to increase: {{counter}}
       </h4>`,
      {
        counter: 1,
        increaseCounter: function () {
          this.counter++;
        }
      }
    );
  }

  private addComponent(template: string, properties?: any = {}) {
    @Component({template})
    class TemplateComponent {}

    @NgModule({declarations: [TemplateComponent]})
    class TemplateModule {}

    const mod = this.compiler.compileModuleAndAllComponentsSync(TemplateModule);
    const factory = mod.componentFactories.find((comp) =>
      comp.componentType === TemplateComponent
    );
    const component = this.container.createComponent(factory);
    Object.assign(component.instance, properties);
    // If properties are changed at a later stage, the change detection
    // may need to be triggered manually:
    // component.changeDetectorRef.detectChanges();
  }
}

@NgModule({
  imports: [ BrowserModule ],
  declarations: [ App ],
  bootstrap: [ App ]
})
export class AppModule {}

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

Recursive function: the process of storing numerous values in variables

There is a code snippet showcasing a recursive function designed to take a number, for example n=5, and produce an array counting down from n to 1 (i.e., [5,4,3,2,1]). The point of confusion arises just before the numbers/values of n are added to countArr ...

Tips on successfully transferring row data that has been clicked or selected from one adjacent table to another table

Currently, I am facing a challenge with two tables that are positioned next to each other. My goal is to append a selected row from the first table to the second table. After successfully extracting data from the selected row and converting it into an arr ...

Is it possible to store a randomly generated variable in JavaScript for future reference?

Currently, I am involved in a project that involves generating random variables to create unique scenes. One specific variable is the location of these scenes. My goal is to be able to generate a location with just one button click. Subsequently, by pressi ...

Using JavaScript to display content on the page after handling a form

Hey there! I'm currently working on a website project where users can input their name and have it displayed on the page. My plan is to achieve this using JavaScript. HTML: <div id='errormsg'></div> <form action='' ...

AngularJS requires that JSON object property values be converted to strings in order to be displayed as actual templates

Each tab click accesses a json array containing unique templates such as ui-grid or c3 chart directive (c3.js). When a specific tab is clicked, the template in string format must be rendered into actual templates like ui-grid, c3-chart, etc. var sampleJs ...

Emphasize the selected page number

My React application contains page numbers, but currently when a page number is clicked, it does not get highlighted or displayed in a different color. The className "text-success" can be added to make the text green. How can I dynamically add this class t ...

Utilizing Next.js and Redux for Enhanced Authentication Experience

I have encountered an issue while trying to authenticate the user upon loading and needing to run the authentication process in the pages/_app.js file. The error I am facing is useReduxContext.js:24 Uncaught Error: could not find react-redux context value; ...

Typescript type/object's conditional property feature

Imagine having a recipe ingredient type structured like this export type RecipeIngredient = { name: string; amount: Number | string; unit: "grams" | "milliliters" | "custom"; }; To illustrate const apples: RecipeIngredient = { name: 'apples&a ...

Include a photo in the notification when utilizing the sendToTopic function

I am looking to utilize the sendToTopic method for sending notifications to a topic. Is there a way to include an image in the notification? It seems that notification.imageUrl is not available as an option. ...

Tips for adding extra spacing between icon and text field using Vuetify

The code snippet below is used for the username section: <v-text-field prepend-icon="fas fa-user" height="60px" placeholder="Username" outlined ></v-text-field> Is there a way to add space between the user ...

Retrieve the most recently updated or added item in a dropdown list using jQuery or AngularJS

Having a multiple select element with the chosen jquery plugin, I am trying to identify the latest selection made using the change event. Struggling to locate a simple method to access the most recent selection, I am currently inspecting the last item in ...

Koffi organized a collection of structured arrays

I am currently using koffi 2.4.2 in a node.js application from koffi.dev and up until now, everything has been running smoothly. However, I have encountered an issue with integrating a native C++ library method that requires a parameter struct defined as f ...

Guide on creating my inaugural HTML embeddable widget?

A client recently requested me to create a JavaScript (MooTools)/HTML/CSS/PHP based game as a deployable widget. This will be my first time developing a widget, so I am seeking advice and insights to help me navigate any potential challenges from experie ...

Using v-for to pass two properties to a single component in VueJS

Hey there! I'm trying to create a v-for loop with a component that has two different props COMPONENT <template> <div class="bg-light rounded p-2 px-5"> <h5> {{ number }}</h5> <h3>{{ item }} ...

What steps do I need to take to modify the MUI Badge component and insert custom text inside?

Is there a way to replace the number with a label next to a new row added to my table using MUI Badge? For example, instead of displaying a number like 4, I want it to show the word "New" as shown in this image: enter image description here This is the co ...

Learn how to automatically update data in Vue JS after making a 'POST,' 'DELETE,' or 'PUT' request in Vue JS 2

Whenever I send a 'POST' or 'DELETE' request, the data doesn't update automatically. I have to manually reload the page to see the updated information. Is there an easy way to refresh the data after making any 'POST' / &a ...

Could the act of one function updating state and another immediately accessing it lead to a potential race condition occurring?

I am faced with a scenario where I have two components - one for uploading files and the other for submitting a form. Each component has its own callback function that needs to trigger a backend request once completed. My objective is to ensure that the ba ...

The issue of the selection option not being cleared after being set to 0 persists in JavaScript

I am facing an issue where I need to reset the select option to `0` when another option is selected. I have tried the code below for this purpose. if (varALPO1MobNum == "0") { var selectElement = $(&apo ...

After generating the token, where is the appropriate place to define the authorization header?

I am currently working on implementing a security system based on tokens. The challenge I am facing is determining the appropriate location to set the authorization header after generating it, in order to validate it across all of my different routes. Belo ...

Incorporating an NPM JavaScript library into Laravel version 8

I've integrated the mobiscroll javascript component library into my new Laravel 8 app by adding the minified css/js files to the public/css and public/js directories. However, I'd like to find a more seamless way to include these components by us ...