我正在准备SPA网站,其中包含数百个类似文章的页面(除了电子商务,登录等)。每篇文章都有自己的URL。我想用Angular2来实现它。 到目前为止我找到的唯一解决方案是:
1。准备数百个Agular2组件,每篇文章一个组件......
...使用指向文章标记的templateUrl。所以我需要数百个类似的组件:
@core.Component({
selector: 'article-1',
templateUrl: 'article1.html'
})
export class Article1 {}
2。使用AsyncRoute
请参阅Lazy Loading of Route Components in Angular2
@core.Component({
selector: 'article-wrapper',
template: '<router-outlet></router-outlet>'
})
@router.RouteConfig([
new router.AsyncRoute({
path: '/article/:id',
loader: () => {
switch (id) {
case 1: return Article1;
case 2: return Article2;
//... repeat it hundreds of times
}
},
name: 'article'
})
])
class ArticleWrapper { }
在Angular1中有ngInclude指令,由于安全问题,Angular2中缺少该指令(参见here)。
[编辑1]代码本身不仅存在问题。问题还在于此解决方案的静态性。如果我需要带有站点地图和动态页面结构的网站 - 添加单个页面需要重新编译整个ES6 JavaScript模块。
[编辑2]“标记x html作为数据”的概念(其中标记不仅是静态HTML而且是具有活动组件的HTML)是整个Web的基本概念(每个CMS在数据库中都有其标记数据)。如果没有Angular2解决方案,它就会否认这个基本概念。我相信必须有一些技巧。
答案 0 :(得分:6)
以下所有解决方案都很棘手。官方Angular团队支持问题是here。
感谢@EricMartinez指点我@alexpods solution:
this.laoder.loadIntoLocation(
toComponent(template, directives),
this.elementRef,
'container'
);
function toComponent(template, directives = []) {
@Component({ selector: 'fake-component' })
@View({ template, directives })
class FakeComponent {}
return FakeComponent;
}
另一个类似的(from @jpleclerc):
@RouteConfig([
new AsyncRoute({
path: '/article/:id',
component: ArticleComponent,
name: 'article'
})
])
...
@Component({ selector: 'base-article', template: '<div id="here"></div>', ... })
class ArticleComponent {
public constructor(private params: RouteParams, private loader: DynamicComponentLoader, private injector: Injector){
}
ngOnInit() {
var id = this.params.get('id');
@Component({ selector: 'article-' + id, templateUrl: 'article-' + id + '.html' })
class ArticleFakeComponent{}
this.loader.loadAsRoot(
ArticleFakeComponent,
'#here'
injector
);
}
}
有点不同(from @peter-svintsitskyi):
// Faking class declaration by creating new instance each time I need.
var component = new (<Type>Function)();
var annotations = [
new Component({
selector: "foo"
}),
new View({
template: text,
directives: [WordDirective]
})
];
// I know this will not work everywhere
Reflect.defineMetadata("annotations", annotations, component);
// compile the component
this.compiler.compileInHost(<Type>component).then((protoViewRef: ProtoViewRef) => {
this.viewContainer.createHostView(protoViewRef);
});