Динамически загружать HTML-шаблон в angular2
Я создал проект с использованием angular-cli
, который содержит AppComponent следующим образом:
import { Component } from '@angular/core';
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent {
title = 'app works!';
}
И app.component.html как
<h1>
Good Morning, {{title}}
</h1>
Поэтому, когда я создаю его с помощью ng build
, он генерирует некоторые файлы, такие как ./dist/main.bundle.js, которые содержат код ниже:
/* 586 */
/***/ function(module, exports) {
module.exports = "<h1>\n Good Morning, {{title}}\n</h1>\n"
/***/ },
/* 587 */
Это означает, что во время сборки компилятор /bundle -er читает html файл и объединяет их в сгенерированный файл js.
Но в моем случае html также является динамическим и управляется содержимым с сервера. Скажем, вместо html мой файл шаблона app.component.jsp и вообще находится на другом сервере или папке.
Также, что JSP файл иногда возвращает <h1>Good Morning, {{title}}</h1>
а иногда <h1>Good Afternoon, {{title}}</h1>
в зависимости от текущего времени сервера.
Как достичь этой функциональности?
Я понимаю, что мне нужно определить какую-то функцию загрузчика: loadDynamicTemplate(template_url)
и необходимо использовать эту функцию-загрузчик в качестве свойства шаблона декоратора компонента. В этом случае, когда генерируется main.bundle.JS, он также будет использовать эту функцию. Поэтому во время выполнения angular вызывается эта функция и загружает HTML ajax и использует его.
Обновление 1
Здесь я нашел некоторую разницу между SystemJS и Webpack. Я также обнаружил, что мы можем загружать файлы HTML во время выполнения, если мы можем использовать SystemJS. Поэтому я считаю, что эту проблему можно решить с помощью конфигурации SystemJS. Но для этого возникает другая проблема, хотя я считаю, что это может быть отдельный вопрос. Поэтому я разместил новый вопрос для сортировки здесь.
Возможно, если этот вопрос будет решен, я попробую с SystemJS, а затем отправьте решение здесь, если это поможет.
Ответы
Ответ 1
Вы можете использовать [ innerHtml] в компоненте my-template
с чем-то вроде этого (я не тестировал):
@Component({
selector: 'my-template',
template: `
<div [innerHtml]="myTemplate">
</div>
`})
export public class MyTemplate {
private myTemplate: any = "";
@Input() url: string;
constructor(http: Http) {
http.get("/path-to-your-jsp").map((html:any) => this.myTemplate = html);
}
}
Ответ 2
Чтобы интерполировать шаблон с помощью некоторого Good Morning, {{title}}
, вы можете использовать компонент Suguru Inatomi ng-dynamic.
Сначала вы должны установить его:
npm install --save ng-dynamic
Затем импортируйте в свой NgModule:
@NgModule({
imports: [
...
DynamicComponentModule.forRoot({}),
...
],
...
})
export class AppModule {}
Наконец, используйте его так:
@Component({
selector: 'app-root',
template: '<div *dynamicComponent="template; context: bindings;"></div>'
})
export class AppComponent {
bindings: any = {title: "Chuck Norris"};
template: string = `
<h1>Good Morning, {{title}}</h1>
`;
constructor(http: Http) {
http.get("/path-to-your-jsp").map((html:string) => this.template = html); //<- You may set bindings in request headers...
}
}
Вы можете использовать компоненты в своем шаблоне, указав SharedModule. Я добавил пользовательскую "мою кнопку" с примерами, например, в примере документации: https://github.com/laco0416/ng-dynamic
Ответ 3
Похоже, что теперь сделать это, чтобы установить responseType, когда вы делаете свой запрос. HttpClient-Запрос данных без JSON
`
@Component({
selector: 'my-template',
template: '<div [innerHtml]="myTemplate"></div>'
})
export public class MyTemplate {
private myTemplate: any = "";
@Input() url: string;
constructor(http: Http) {
http.get("/path-to-your-jsp", { responseType: 'text' })
.subscribe(
(data: string) => {
this.myTemplate = html;
}
);
}
}
`