Dynamic plugins in angular
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
add a comment |
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
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
add a comment |
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
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
javascript angular typescript
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
add a comment |
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
add a comment |
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
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