it-swarm.com.ru

Angular 2/4 компонент с динамическим шаблоном или templateUrl

Я пытался найти решение для этого везде.

У меня есть проект с разными "скинами", которые в основном разные наборы шаблонов/Css.

Я пытаюсь, чтобы мои компоненты использовали скин, основанный на переменной THEME_DIR.

К сожалению, я не могу найти, как это сделать. Я посмотрел в Динамический загрузчик компонентов на angular.io без успеха.

Я также посмотрел несколько ответов здесь, но безуспешно.

У кого-нибудь есть идея?

Это то, что я пробовал до сих пор:

import { ComponentFactoryResolver, ViewContainerRef } from '@angular/core';

// @Component({
//     templateUrl: '../../assets/theme/'+THEME_DIR+'/login.template.html',
// })

export class LoginComponent implements, AfterViewInit {


    private log = Log.create('LoginPage');

    constructor(private mzksLsRequestService: MzkLsRequestService,
                private componentFactoryResolver: ComponentFactoryResolver,
                public viewContainerRef: ViewContainerRef) {
    }



    ngAfterViewInit() {
        let componentFactory = this.componentFactoryResolver.resolveComponentFactory(new Component({
            templateUrl: '../../assets/theme/default/login.template.html',
        }));
        let viewContainerRef = this.viewContainerRef;
        viewContainerRef.clear();
        let componentRef = viewContainerRef.createComponent(componentFactory);

    }

}
6
millerf

Вы можете сделать это так:

import {
  Compiler, Component, Injector, VERSION, ViewChild, NgModule, NgModuleRef,
  ViewContainerRef
} from '@angular/core';


@Component({
  selector: 'my-app',
  template: `
      <h1>Hello {{name}}</h1>
      <ng-container #vc></ng-container>
  `
})
export class AppComponent {
  @ViewChild('vc', {read: ViewContainerRef}) vc;
  name = `Angular! v${VERSION.full}`;

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

  ngAfterViewInit() {
    const tmpCmp = Component({
        moduleId: module.id, templateUrl: './e.component.html'})(class {
    });
    const tmpModule = NgModule({declarations: [tmpCmp]})(class {
    });

    this._compiler.compileModuleAndAllComponentsAsync(tmpModule)
      .then((factories) => {
        const f = factories.componentFactories[0];
        const cmpRef = f.create(this._injector, [], null, this._m);
        cmpRef.instance.name = 'dynamic';
        this.vc.insert(cmpRef.hostView);
      })
  }
}

Просто убедитесь, что URL-адрес правильный и шаблон загружен в клиент.

Read вот что вам нужно знать о динамических компонентах в Angular для более подробной информации.

10
Max Koretskyi aka Wizard

У меня была проблема при попытке загрузить динамически шаблоны с сервера (я хотел сделать проверку безопасности, перевод на стороне сервера, прежде чем обслуживать HTML.

Я решил это после изменения конфигурации веб-пакета. Фактически, после выполнения ng eject, он создал webpack.config.js, который содержит загрузчик .ts @ngtools/webpack и:

new AotPlugin({
  "mainPath": "main.ts",
  "replaceExport": false,
  "hostReplacementPaths": {
    "environments\\environment.ts": "environments\\environment.ts"
  },
  "exclude": [],
  "tsConfigPath": "src/main/front/tsconfig.app.json",
  "skipCodeGeneration": true
})

Это последнее, происхождение проблемы. Это касается AOT (Aigh Of Time). Согласно документации: Ngtools в разделе опций упоминается:

skipCodeGeneration. Необязательно, по умолчанию используется значение false. Отключить код генерация и не рефакторинг кода для начальной загрузки. Это заменяет templateUrl: "string" на template: require ("string")

Если вы не хотите, чтобы ваш templateUrl был скомпилирован AOT, я рекомендую вам удалить AotPlugin и использовать загрузчик ts вместо @ ngtools/webpack, см .:

ts-loader

Правило для ts будет выглядеть так:

{
    test: /\.tsx?$/,
    loader: 'ts-loader'
}

Теперь вы можете загружать свежие шаблоны из относительного URL по запросу. Пример :

@Component({
    selector : "custom-component",
    templateUrl : "/my_custom_url_on_server"
})
export class CustomComponent {
}

Смотрите Выпуск

1
Yacine