Dynamic plugins in angular










1















The question is how one can achieve similar "thing" in Angular 2+ to that I managed to do in AngularJS. What the "thing" is I will describe below.



Question description



So the process that I created in AngularJS can be described as follows:



  • We want to inject a custom dynamic content into a page, let's call it a plugin

  • That content is not defined in the web-client, instead it is being retrieved from a server in a structured form

That is we receive from the server html and js files that are necessary for the plugin to function and we load and display on the page. On the client I create an AngularJs directive to hold the necessary logic if the plugin.



Here is the code example for javascript plugin code:



() => 
return
templateUrl: 'directive-template-name',
restrict: "E",
controller: ['$scope', ... /* other dependecies */, function ($scope, ...)
/* directive code */
]
;



Here is the code example for plugin loader code:



// evaluate js function and compile directive
var diretiveFactory = eval(content.jsFile);

// AngularJS CompileProvider
CompileProvider.directive.apply(null, [content.name, diretiveFactory]);

// append html code to element using angular
var wrapper = angular.element("#" + wrapperName);
wrapper.html(requestedDirective[0].htmlContent);

// initialize dynamic content
var wrapperScope = wrapper.scope();
this.$compile(wrapper)(wrapperScope);


As one can see, this method allows to load a valid javascript and "compile" it into a AngularJS directive and then display it on the page at will.



Angular 2+



The problem with new angular is that concept of the directive, as far as I understand, is replace by a concept of component. Moreover, all client-side code is now written in typescript and transpiled into javascript for the client's browser. As far as I understand, all dependencies are being resolved in the traspilation process.



That creates some problems that prevent from creating dynamic plugins for Angular 2+:



  • A do not know how to inject dependencies into a dynamically created component as I do not know what exactly do I need when the transpilation happens.

  • Let's say I want several components to co-exist simultaneously (for example a parent dynamic components that holds children componets) and be able to communicate, in the case of AngularJs I could solve this problem by using scope variable. In case of Angular 2+ components are isolated so how to I go about this problem.

  • Moreover, I do not know how one can go about creating ViewContainerRef to hold the dynamically created component in evaluated javascript code. (See code examples below)

I will provide code examples of I got so far below. Content loader typescript code:



//some imports
import Component, ComponentRef, Compiler, Injector, NgModule, NgModuleRef, ViewContainerRef from '@angular/core';

// plugin content structure
class DynamicPageModel
name: string;
htmlFile: string;
jsFile: string;


export class DynamicContentService

constructor(
private _compiler: Compiler,
private _injector: Injector,
private _m: NgModuleRef<any>
)

public LoadDynamicContent(container: ViewContainerRef, content: DynamicPageModel)
// evaluate js function and compile component
var tmpCmp = Component(
template: content.htmlFile,
selector: content.name
)(eval(content.jsFile)());
var tmpModule = NgModule(declarations: [tmpCmp as any])(class );
var factories = this._compiler.compileModuleAndAllComponentsSync(tmpModule)
var f = factories.componentFactories[0];

var cmpRef = f.create(this._injector, , null, this._m);

// insert component into the container
container.insert(cmpRef.hostView);




For reference to what is going on in this piece of code, I got it from here.



Plugin example javascript code:



() => 
function dynamicMain()
this.componentName = 'Dynamic Example Main';

return dynamicExampleMain;



As one can see, this is quite simple dynamic plugin that is unable to use any services or other components as it is unable to inject them into itself.



Expected answer



As an answer to my question I would like to hear a solution(s) to the problems I encountered when trying to create dynamic plugins for the Angular 2+.



If you know a better approach to creating dynamic plugins (remember: they are retrieved from a server) at run time in Angular 2+, I would like to hear it too.










share|improve this question
























  • Have you tried these: 1) angular.io/guide/dynamic-component-loader 2) angular.io/guide/elements

    – yccteam
    Nov 12 '18 at 13:51











  • You see, I cannot write plugins in the typescript as a trasnpilation process is over before the loading of dynamic plugin. Moreover I cannot define plugin code in the Angular client application. It is retrieved from a server separately.

    – Konstantin
    Nov 12 '18 at 14:21















1















The question is how one can achieve similar "thing" in Angular 2+ to that I managed to do in AngularJS. What the "thing" is I will describe below.



Question description



So the process that I created in AngularJS can be described as follows:



  • We want to inject a custom dynamic content into a page, let's call it a plugin

  • That content is not defined in the web-client, instead it is being retrieved from a server in a structured form

That is we receive from the server html and js files that are necessary for the plugin to function and we load and display on the page. On the client I create an AngularJs directive to hold the necessary logic if the plugin.



Here is the code example for javascript plugin code:



() => 
return
templateUrl: 'directive-template-name',
restrict: "E",
controller: ['$scope', ... /* other dependecies */, function ($scope, ...)
/* directive code */
]
;



Here is the code example for plugin loader code:



// evaluate js function and compile directive
var diretiveFactory = eval(content.jsFile);

// AngularJS CompileProvider
CompileProvider.directive.apply(null, [content.name, diretiveFactory]);

// append html code to element using angular
var wrapper = angular.element("#" + wrapperName);
wrapper.html(requestedDirective[0].htmlContent);

// initialize dynamic content
var wrapperScope = wrapper.scope();
this.$compile(wrapper)(wrapperScope);


As one can see, this method allows to load a valid javascript and "compile" it into a AngularJS directive and then display it on the page at will.



Angular 2+



The problem with new angular is that concept of the directive, as far as I understand, is replace by a concept of component. Moreover, all client-side code is now written in typescript and transpiled into javascript for the client's browser. As far as I understand, all dependencies are being resolved in the traspilation process.



That creates some problems that prevent from creating dynamic plugins for Angular 2+:



  • A do not know how to inject dependencies into a dynamically created component as I do not know what exactly do I need when the transpilation happens.

  • Let's say I want several components to co-exist simultaneously (for example a parent dynamic components that holds children componets) and be able to communicate, in the case of AngularJs I could solve this problem by using scope variable. In case of Angular 2+ components are isolated so how to I go about this problem.

  • Moreover, I do not know how one can go about creating ViewContainerRef to hold the dynamically created component in evaluated javascript code. (See code examples below)

I will provide code examples of I got so far below. Content loader typescript code:



//some imports
import Component, ComponentRef, Compiler, Injector, NgModule, NgModuleRef, ViewContainerRef from '@angular/core';

// plugin content structure
class DynamicPageModel
name: string;
htmlFile: string;
jsFile: string;


export class DynamicContentService

constructor(
private _compiler: Compiler,
private _injector: Injector,
private _m: NgModuleRef<any>
)

public LoadDynamicContent(container: ViewContainerRef, content: DynamicPageModel)
// evaluate js function and compile component
var tmpCmp = Component(
template: content.htmlFile,
selector: content.name
)(eval(content.jsFile)());
var tmpModule = NgModule(declarations: [tmpCmp as any])(class );
var factories = this._compiler.compileModuleAndAllComponentsSync(tmpModule)
var f = factories.componentFactories[0];

var cmpRef = f.create(this._injector, , null, this._m);

// insert component into the container
container.insert(cmpRef.hostView);




For reference to what is going on in this piece of code, I got it from here.



Plugin example javascript code:



() => 
function dynamicMain()
this.componentName = 'Dynamic Example Main';

return dynamicExampleMain;



As one can see, this is quite simple dynamic plugin that is unable to use any services or other components as it is unable to inject them into itself.



Expected answer



As an answer to my question I would like to hear a solution(s) to the problems I encountered when trying to create dynamic plugins for the Angular 2+.



If you know a better approach to creating dynamic plugins (remember: they are retrieved from a server) at run time in Angular 2+, I would like to hear it too.










share|improve this question
























  • Have you tried these: 1) angular.io/guide/dynamic-component-loader 2) angular.io/guide/elements

    – yccteam
    Nov 12 '18 at 13:51











  • You see, I cannot write plugins in the typescript as a trasnpilation process is over before the loading of dynamic plugin. Moreover I cannot define plugin code in the Angular client application. It is retrieved from a server separately.

    – Konstantin
    Nov 12 '18 at 14:21













1












1








1








The question is how one can achieve similar "thing" in Angular 2+ to that I managed to do in AngularJS. What the "thing" is I will describe below.



Question description



So the process that I created in AngularJS can be described as follows:



  • We want to inject a custom dynamic content into a page, let's call it a plugin

  • That content is not defined in the web-client, instead it is being retrieved from a server in a structured form

That is we receive from the server html and js files that are necessary for the plugin to function and we load and display on the page. On the client I create an AngularJs directive to hold the necessary logic if the plugin.



Here is the code example for javascript plugin code:



() => 
return
templateUrl: 'directive-template-name',
restrict: "E",
controller: ['$scope', ... /* other dependecies */, function ($scope, ...)
/* directive code */
]
;



Here is the code example for plugin loader code:



// evaluate js function and compile directive
var diretiveFactory = eval(content.jsFile);

// AngularJS CompileProvider
CompileProvider.directive.apply(null, [content.name, diretiveFactory]);

// append html code to element using angular
var wrapper = angular.element("#" + wrapperName);
wrapper.html(requestedDirective[0].htmlContent);

// initialize dynamic content
var wrapperScope = wrapper.scope();
this.$compile(wrapper)(wrapperScope);


As one can see, this method allows to load a valid javascript and "compile" it into a AngularJS directive and then display it on the page at will.



Angular 2+



The problem with new angular is that concept of the directive, as far as I understand, is replace by a concept of component. Moreover, all client-side code is now written in typescript and transpiled into javascript for the client's browser. As far as I understand, all dependencies are being resolved in the traspilation process.



That creates some problems that prevent from creating dynamic plugins for Angular 2+:



  • A do not know how to inject dependencies into a dynamically created component as I do not know what exactly do I need when the transpilation happens.

  • Let's say I want several components to co-exist simultaneously (for example a parent dynamic components that holds children componets) and be able to communicate, in the case of AngularJs I could solve this problem by using scope variable. In case of Angular 2+ components are isolated so how to I go about this problem.

  • Moreover, I do not know how one can go about creating ViewContainerRef to hold the dynamically created component in evaluated javascript code. (See code examples below)

I will provide code examples of I got so far below. Content loader typescript code:



//some imports
import Component, ComponentRef, Compiler, Injector, NgModule, NgModuleRef, ViewContainerRef from '@angular/core';

// plugin content structure
class DynamicPageModel
name: string;
htmlFile: string;
jsFile: string;


export class DynamicContentService

constructor(
private _compiler: Compiler,
private _injector: Injector,
private _m: NgModuleRef<any>
)

public LoadDynamicContent(container: ViewContainerRef, content: DynamicPageModel)
// evaluate js function and compile component
var tmpCmp = Component(
template: content.htmlFile,
selector: content.name
)(eval(content.jsFile)());
var tmpModule = NgModule(declarations: [tmpCmp as any])(class );
var factories = this._compiler.compileModuleAndAllComponentsSync(tmpModule)
var f = factories.componentFactories[0];

var cmpRef = f.create(this._injector, , null, this._m);

// insert component into the container
container.insert(cmpRef.hostView);




For reference to what is going on in this piece of code, I got it from here.



Plugin example javascript code:



() => 
function dynamicMain()
this.componentName = 'Dynamic Example Main';

return dynamicExampleMain;



As one can see, this is quite simple dynamic plugin that is unable to use any services or other components as it is unable to inject them into itself.



Expected answer



As an answer to my question I would like to hear a solution(s) to the problems I encountered when trying to create dynamic plugins for the Angular 2+.



If you know a better approach to creating dynamic plugins (remember: they are retrieved from a server) at run time in Angular 2+, I would like to hear it too.










share|improve this question
















The question is how one can achieve similar "thing" in Angular 2+ to that I managed to do in AngularJS. What the "thing" is I will describe below.



Question description



So the process that I created in AngularJS can be described as follows:



  • We want to inject a custom dynamic content into a page, let's call it a plugin

  • That content is not defined in the web-client, instead it is being retrieved from a server in a structured form

That is we receive from the server html and js files that are necessary for the plugin to function and we load and display on the page. On the client I create an AngularJs directive to hold the necessary logic if the plugin.



Here is the code example for javascript plugin code:



() => 
return
templateUrl: 'directive-template-name',
restrict: "E",
controller: ['$scope', ... /* other dependecies */, function ($scope, ...)
/* directive code */
]
;



Here is the code example for plugin loader code:



// evaluate js function and compile directive
var diretiveFactory = eval(content.jsFile);

// AngularJS CompileProvider
CompileProvider.directive.apply(null, [content.name, diretiveFactory]);

// append html code to element using angular
var wrapper = angular.element("#" + wrapperName);
wrapper.html(requestedDirective[0].htmlContent);

// initialize dynamic content
var wrapperScope = wrapper.scope();
this.$compile(wrapper)(wrapperScope);


As one can see, this method allows to load a valid javascript and "compile" it into a AngularJS directive and then display it on the page at will.



Angular 2+



The problem with new angular is that concept of the directive, as far as I understand, is replace by a concept of component. Moreover, all client-side code is now written in typescript and transpiled into javascript for the client's browser. As far as I understand, all dependencies are being resolved in the traspilation process.



That creates some problems that prevent from creating dynamic plugins for Angular 2+:



  • A do not know how to inject dependencies into a dynamically created component as I do not know what exactly do I need when the transpilation happens.

  • Let's say I want several components to co-exist simultaneously (for example a parent dynamic components that holds children componets) and be able to communicate, in the case of AngularJs I could solve this problem by using scope variable. In case of Angular 2+ components are isolated so how to I go about this problem.

  • Moreover, I do not know how one can go about creating ViewContainerRef to hold the dynamically created component in evaluated javascript code. (See code examples below)

I will provide code examples of I got so far below. Content loader typescript code:



//some imports
import Component, ComponentRef, Compiler, Injector, NgModule, NgModuleRef, ViewContainerRef from '@angular/core';

// plugin content structure
class DynamicPageModel
name: string;
htmlFile: string;
jsFile: string;


export class DynamicContentService

constructor(
private _compiler: Compiler,
private _injector: Injector,
private _m: NgModuleRef<any>
)

public LoadDynamicContent(container: ViewContainerRef, content: DynamicPageModel)
// evaluate js function and compile component
var tmpCmp = Component(
template: content.htmlFile,
selector: content.name
)(eval(content.jsFile)());
var tmpModule = NgModule(declarations: [tmpCmp as any])(class );
var factories = this._compiler.compileModuleAndAllComponentsSync(tmpModule)
var f = factories.componentFactories[0];

var cmpRef = f.create(this._injector, , null, this._m);

// insert component into the container
container.insert(cmpRef.hostView);




For reference to what is going on in this piece of code, I got it from here.



Plugin example javascript code:



() => 
function dynamicMain()
this.componentName = 'Dynamic Example Main';

return dynamicExampleMain;



As one can see, this is quite simple dynamic plugin that is unable to use any services or other components as it is unable to inject them into itself.



Expected answer



As an answer to my question I would like to hear a solution(s) to the problems I encountered when trying to create dynamic plugins for the Angular 2+.



If you know a better approach to creating dynamic plugins (remember: they are retrieved from a server) at run time in Angular 2+, I would like to hear it too.







javascript angular typescript






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 12 '18 at 13:54









georgeawg

33k104968




33k104968










asked Nov 12 '18 at 13:46









KonstantinKonstantin

61




61












  • Have you tried these: 1) angular.io/guide/dynamic-component-loader 2) angular.io/guide/elements

    – yccteam
    Nov 12 '18 at 13:51











  • You see, I cannot write plugins in the typescript as a trasnpilation process is over before the loading of dynamic plugin. Moreover I cannot define plugin code in the Angular client application. It is retrieved from a server separately.

    – Konstantin
    Nov 12 '18 at 14:21

















  • Have you tried these: 1) angular.io/guide/dynamic-component-loader 2) angular.io/guide/elements

    – yccteam
    Nov 12 '18 at 13:51











  • You see, I cannot write plugins in the typescript as a trasnpilation process is over before the loading of dynamic plugin. Moreover I cannot define plugin code in the Angular client application. It is retrieved from a server separately.

    – Konstantin
    Nov 12 '18 at 14:21
















Have you tried these: 1) angular.io/guide/dynamic-component-loader 2) angular.io/guide/elements

– yccteam
Nov 12 '18 at 13:51





Have you tried these: 1) angular.io/guide/dynamic-component-loader 2) angular.io/guide/elements

– yccteam
Nov 12 '18 at 13:51













You see, I cannot write plugins in the typescript as a trasnpilation process is over before the loading of dynamic plugin. Moreover I cannot define plugin code in the Angular client application. It is retrieved from a server separately.

– Konstantin
Nov 12 '18 at 14:21





You see, I cannot write plugins in the typescript as a trasnpilation process is over before the loading of dynamic plugin. Moreover I cannot define plugin code in the Angular client application. It is retrieved from a server separately.

– Konstantin
Nov 12 '18 at 14:21












0






active

oldest

votes











Your Answer






StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "1"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
autoActivateHeartbeat: false,
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader:
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
,
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);













draft saved

draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53263533%2fdynamic-plugins-in-angular%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown

























0






active

oldest

votes








0






active

oldest

votes









active

oldest

votes






active

oldest

votes















draft saved

draft discarded
















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid


  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.

To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53263533%2fdynamic-plugins-in-angular%23new-answer', 'question_page');

);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

How to how show current date and time by default on contact form 7 in WordPress without taking input from user in datetimepicker

Syphilis

Darth Vader #20