Skip to content

Commit 09a6f00

Browse files
committed
Initial commit
0 parents  commit 09a6f00

19 files changed

+3837
-0
lines changed

.editorconfig

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# Editor configuration, see http://editorconfig.org
2+
root = true
3+
4+
[*]
5+
charset = utf-8
6+
indent_style = space
7+
indent_size = 2
8+
insert_final_newline = true
9+
trim_trailing_whitespace = true
10+
11+
[*.md]
12+
max_line_length = off
13+
trim_trailing_whitespace = false

.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
.vscode/*
2+
!.vscode/settings.json
3+
node_modules/*
4+
dist/*
5+
compiled/*

.npmignore

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
node_modules
2+
.vscode
3+
src
4+
compiled
5+
tslint.json
6+
tsconfig*.json
7+
rollup.config.js

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2016 Alex Malkevich
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.MD

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# ng-dynamic-component
2+
3+
> Dynamic components with full life-cycle support for inputs and outputs
4+
5+
## Installation
6+
7+
```bash
8+
$ npm install ng-dynamic-component --save
9+
```
10+
11+
## License
12+
13+
MIT © [Alex Malkevich]([email protected])

package.json

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
{
2+
"name": "ng-dynamic-component",
3+
"version": "0.0.1",
4+
"description": "Dynamic components with full life-cycle support for inputs and outputs",
5+
"main": "dist/bundles/ng-dynamic-component.umd.js",
6+
"module": "dist/index.js",
7+
"scripts": {
8+
"prebuild": "rimraf dist compiled",
9+
"build": "npm-run-all -s build:*",
10+
"build:main": "ngc",
11+
"build:umd": "rollup -c rollup.config.js",
12+
"postbuild:umd": "uglifyjs -c --screw-ie8 --comments -o dist/bundles/ng-dynamic-component.umd.min.js dist/bundles/ng-dynamic-component.umd.js",
13+
"test": "echo \"Error: no test specified\" && exit 1"
14+
},
15+
"keywords": [
16+
"angular",
17+
"angular2",
18+
"ng",
19+
"dynamic",
20+
"component",
21+
"input",
22+
"output",
23+
"life-cycle"
24+
],
25+
"author": "Alex Malkevich <[email protected]>",
26+
"license": "MIT",
27+
"peerDependencies": {
28+
"@angular/common": "^2.4.7"
29+
},
30+
"devDependencies": {
31+
"@angular/common": "^2.4.7",
32+
"@angular/compiler": "^2.4.7",
33+
"@angular/compiler-cli": "^2.4.7",
34+
"@angular/core": "^2.4.7",
35+
"@angular/platform-browser": "^2.4.7",
36+
"@angular/platform-browser-dynamic": "^2.4.7",
37+
"@angular/platform-server": "^2.4.7",
38+
"@types/jasmine": "^2.5.43",
39+
"angular2-template-loader": "^0.6.2",
40+
"awesome-typescript-loader": "^3.0.4",
41+
"codelyzer": "^2.0.0",
42+
"commitizen": "^2.9.5",
43+
"cz-conventional-changelog": "^1.2.0",
44+
"npm-run-all": "^4.0.0",
45+
"rimraf": "^2.5.4",
46+
"rollup": "^0.41.4",
47+
"rollup-globals-regex": "^0.0.1",
48+
"rollup-plugin-node-resolve": "^2.0.0",
49+
"rxjs": "^5.1.0",
50+
"tslib": "^1.5.0",
51+
"tslint": "^4.4.2",
52+
"typescript": "^2.2.0",
53+
"uglifyjs": "^2.4.10",
54+
"webpack": "^2.2.1",
55+
"webpack-dev-server": "^2.3.0",
56+
"zone.js": "^0.7.7"
57+
},
58+
"engines": {
59+
"node": ">=6.0.0"
60+
},
61+
"config": {
62+
"commitizen": {
63+
"path": "./node_modules/cz-conventional-changelog"
64+
}
65+
}
66+
}

rollup.config.js

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import nodeResolve from 'rollup-plugin-node-resolve';
2+
import { globalsRegex, GLOBAL } from 'rollup-globals-regex';
3+
4+
export default {
5+
entry: 'dist/index.js',
6+
dest: 'dist/bundles/ng-dynamic-component.umd.js',
7+
format: 'umd',
8+
moduleName: 'dynamicComponent',
9+
plugins: [
10+
nodeResolve({ jsnext: true, browser: true })
11+
],
12+
globals: globalsRegex({
13+
'tslib': 'tslib',
14+
[GLOBAL.NG2]: GLOBAL.NG2.TPL,
15+
[GLOBAL.RX]: GLOBAL.RX.TPL,
16+
}),
17+
external: (moduleId) => {
18+
if (/^(\@angular|rxjs)\//.test(moduleId)) {
19+
return true;
20+
}
21+
22+
return false;
23+
}
24+
};

src/dynamic/component-injector.ts

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import { ComponentRef, OpaqueToken } from '@angular/core';
2+
3+
export interface ComponentInjector {
4+
componentRef: ComponentRef<any>;
5+
}
6+
7+
export const COMPONENT_INJECTOR = new OpaqueToken('ComponentInjector');

src/dynamic/custom-simple-change.ts

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import { SimpleChange } from '@angular/core';
2+
3+
export const UNINITIALIZED = Object.freeze({ __uninitialized: true });
4+
5+
export class CustomSimpleChange extends SimpleChange {
6+
isFirstChange() {
7+
return this.previousValue === UNINITIALIZED || super.isFirstChange();
8+
}
9+
}

src/dynamic/dynamic.component.spec.ts

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/* tslint:disable:no-unused-variable */
2+
import { async, ComponentFixture, TestBed } from '@angular/core/testing';
3+
import { By } from '@angular/platform-browser';
4+
import { DebugElement } from '@angular/core';
5+
6+
import { DynamicComponent } from './dynamic.component';
7+
8+
describe('DynamicComponent', () => {
9+
let component: DynamicComponent;
10+
let fixture: ComponentFixture<DynamicComponent>;
11+
12+
beforeEach(async(() => {
13+
TestBed.configureTestingModule({
14+
declarations: [ DynamicComponent ]
15+
})
16+
.compileComponents();
17+
}));
18+
19+
beforeEach(() => {
20+
fixture = TestBed.createComponent(DynamicComponent);
21+
component = fixture.componentInstance;
22+
fixture.detectChanges();
23+
});
24+
25+
it('should create', () => {
26+
expect(component).toBeTruthy();
27+
});
28+
});

src/dynamic/dynamic.component.ts

+59
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
import { ComponentInjector } from './component-injector';
2+
import {
3+
Component,
4+
ComponentFactoryResolver,
5+
ComponentRef,
6+
Injector,
7+
Input,
8+
OnChanges,
9+
Provider,
10+
ReflectiveInjector,
11+
SimpleChanges,
12+
Type,
13+
ViewContainerRef
14+
} from '@angular/core';
15+
16+
@Component({
17+
selector: 'app-dynamic',
18+
template: ''
19+
})
20+
export class DynamicComponent implements OnChanges, ComponentInjector {
21+
22+
@Input() appDynamicComponent: Type<any>;
23+
@Input() appDynamicInjector: Injector;
24+
@Input() appDynamicProviders: Provider[];
25+
@Input() appDynamicContent: any[][];
26+
27+
componentRef: ComponentRef<any>;
28+
29+
constructor(
30+
private _vcr: ViewContainerRef,
31+
private _cfr: ComponentFactoryResolver
32+
) { }
33+
34+
ngOnChanges(changes: SimpleChanges) {
35+
if (changes['appDynamicComponent']) {
36+
this.createDynamicComponent();
37+
}
38+
}
39+
40+
createDynamicComponent() {
41+
this._vcr.clear();
42+
43+
this.componentRef = this._vcr.createComponent(
44+
this._cfr.resolveComponentFactory(this.appDynamicComponent),
45+
0, this._resolveInjector(), this.appDynamicContent
46+
);
47+
}
48+
49+
private _resolveInjector(): Injector {
50+
let injector = this.appDynamicInjector || this._vcr.parentInjector;
51+
52+
if (this.appDynamicProviders) {
53+
injector = ReflectiveInjector.resolveAndCreate(this.appDynamicProviders, injector);
54+
}
55+
56+
return injector;
57+
}
58+
59+
}

src/dynamic/dynamic.directive.spec.ts

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/* tslint:disable:no-unused-variable */
2+
3+
import { TestBed, async } from '@angular/core/testing';
4+
import { DynamicDirective } from './dynamic.directive';
5+
6+
describe('Directive: Dynamic', () => {
7+
it('should create an instance', () => {
8+
const directive = new DynamicDirective(<any>{}, <any>{}, <any>{});
9+
expect(directive).toBeTruthy();
10+
});
11+
});

0 commit comments

Comments
 (0)