@Directive({ selector: 'html-outlet' })
export class HtmlOutlet {
@Input() html: string;
cmpRef: ComponentRef<any>;
constructor(private vcRef: ViewContainerRef, private compiler: Compiler) { }
ngOnChanges() {
const html = this.html;
if (!html) return;
if(this.cmpRef) {
this.cmpRef.destroy();
}
@Component({
selector: 'dynamic-comp',
template: html
})
class DynamicHtmlComponent {};
@NgModule({
imports: [CommonModule],
declarations: [DynamicHtmlComponent]
})
class DynamicHtmlModule {}
this.compiler.compileModuleAndAllComponentsAsync(DynamicHtmlModule)
.then(factory => {
const moduleRef = factory.ngModuleFactory.create(this.vcRef.parentInjector);
const compFactory = factory.componentFactories.find(x => x.componentType === DynamicHtmlComponent);
const cmpRef = this.vcRef.createComponent(compFactory, 0, moduleRef.injector);
});
}
ngOnDestroy() {
if(this.cmpRef) {
this.cmpRef.destroy();
}
}
}
<html-outlet [html]="html"></html-outlet>
template
может быть templateUrl
Параметры @Input
@Output
можно накрутить потом если надоComponentFactoryResolver.resolveComponentFactory
entryComponents
массив вашего модуля или компонентаANALYZE_FOR_ENTRY_COMPONENTS
провайдерNotificationBellComponent
в declarations
массиве@NgModule({
imports: [CommonModule, SharedModule],
declarations: [NotificationComponent, NotificationBellComponent],
exports: [NotificationComponent, NotificationBellComponent],
providers: [NotificationService]
})
You can export any declarable class — components, directives, and pipes — whether it is declared in this module or in an imported module.
You can re-export entire imported modules which effectively re-exports all of their exported classes. A module can even export a module that it doesn't import.
NotificationModule
@NgModule({
imports: [CommonModule, SharedModule, NotificationModule],
declarations: [ToolbarComponent],
exports: [ToolbarComponent]
})
@Pipe({
name: 'someRand',
pure: false
})
export class RandomPipe implements PipeTransform {
constructor(private cdRef:ChangeDetectorRef) {}
pipe: AsyncPipe;
obs: Observable<string>;
transform(value:string):any {
if (!this.pipe) {
this.pipe = new AsyncPipe(this.cdRef);
this.obs = new Observable<string>(observer=>{
observer.next('rand1');
setTimeout(()=>{
observer.next('rand@2');
}, 600)
});
}
return this.pipe.transform(this.obs);
}
}
providers: [
GlobalService,
{
provide: APP_INITIALIZER,
useFactory: (service: GlobalService) => () => service.init(),
deps: [GlobalService], multi: true
}
],
@Injectable()
export class GlobalService {
data: any;
constructor(private http: Http) { }
init(): Promise<any> {
var promise = this.http.get('src/data.json').map(res => res.json()).toPromise();
promise.then(data => this.data = data);
return promise;
}
}
export class AppComponent {
constructor(private service: GlobalService) {
console.log(service.data);
}
}
import {
Component,
Directive,
Input,
ComponentFactory,
ComponentMetadata,
ComponentResolver,
ReflectiveInjector,
ViewContainerRef
} from '@angular/core';
function createComponentFactory(resolver: ComponentResolver,
metadata: ComponentMetadata): Promise<ComponentFactory<any>> {
const cmp = class DynamicComponent { };
const decoratedCmp = Component(metadata)(cmp);
return resolver.resolveComponent(decoratedCmp);
}
@Directive({
selector: 'html-outlet'
})
export class HtmlOutlet {
@Input() html: string;
constructor(private vcRef: ViewContainerRef, private resolver: ComponentResolver) {}
ngOnChanges() {
if (!this.html) return;
const metadata = new ComponentMetadata({
selector: 'dynamic-html',
template: this.html,
});
createComponentFactory(this.resolver, metadata)
.then(factory => {
const inj = ReflectiveInjector.fromResolvedProviders([], this.vcRef.parentInjector);
this.vcRef.createComponent(factory, 0, inj, []);
});
}
}
<html-outlet [html]="html"></html-outlet>
import {Component, Inject, NgZone} from 'angular2/core'; // import NgZone
...
constructor(@Inject(UsersService) private UsersService, private zone:NgZone) {
UsersService.users.subscribe(newUsers => {
this.zone.run(()=> {
this.currentUsers = newUsers;
});
});
UsersService.fetchUsers();
}
EXCEPTION: Error during instantiation of LocationStrategy! (RouterLink -> Router -> Location -> LocationStrategy).
import {bootstrap} from 'angular2/platform/browser';
import {App} from './app';
import {ROUTER_PROVIDERS, LocationStrategy, HashLocationStrategy} from 'angular2/router';
import {provide} from 'angular2/core';
bootstrap(App, [
ROUTER_PROVIDERS,
provide(LocationStrategy, { useClass: HashLocationStrategy })])
.catch(err => console.error(err));
что же это за чудо такое?
require('es6-promise!./about/about')
является вызовом загрузки модуля с помощью переопределенного лоадера, а не просто лоадера, который прописан в webpack.config.js этой сборкиloaders: [
// See: https://github.com/s-panferov/awesome-typescript-loader
{test: /\.ts$/, loader: 'awesome-typescript-loader', exclude: [/\.(spec|e2e)\.ts$/]},
require("......app\\about\\about.ts")[namespace]
export class About {
ngOnInit() {
console.log('hello `About` component');
}
из компонента var gulpif = require('gulp-if');
var uglify = require('gulp-uglify');
var notMinified = function (file) {
return !/\.min\.js/.test(file.path);
};
gulp.task('task', function() {
gulp.src('./src/*.js')
.pipe(gulpif(notMinified , uglify()))
.pipe(gulp.dest('./dist/'));
});