简体   繁体   English

如何在Angular2中实现数百页的网站

[英]How to realize website with hundreds of pages in Angular2

I am preparing SPA website containing hundreds of article-like pages (apart from eCommerce, login etc.). 我正在准备SPA网站,其中包含数百个类似文章的页面(除了电子商务,登录等)。 Every article has its own URL. 每篇文章都有自己的URL。 I want to realize it using Angular2. 我想用Angular2来实现它。 The only solution I found so far is: 到目前为止我找到的唯一解决方案是:

1. to prepare hundreds of Agular2 components, one component for every article... 1.准备数百个Agular2组件,每篇文章一个组件......

...with templateUrl pointing to article markup. ...使用指向文章标记的templateUrl。 So I will need hundreds of components similar to: 所以我需要数百种类似的组件:

@core.Component({
  selector: 'article-1',
  templateUrl: 'article1.html'
})
export class Article1 {}

2. to display an article using AsyncRoute 2.使用AsyncRoute显示文章

see Lazy Loading of Route Components in Angular2 请参阅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 { }

In Angular1 there was ngInclude directive, which is missing in Angular2 due to the security issues (see here ). 在Angular1中有ngInclude指令,由于安全问题,Angular2中缺少该指令(参见此处 )。

[Edit 1] There is not only problem with the code itself. [编辑1]代码本身不仅存在问题。 Problem is also with static nature of this solution. 问题还在于此解决方案的静态性质 If I need website with sitemap and dynamic page structure - adding a single page needs recompilation of the whole ES6 JavaScript module. 如果我需要带有站点地图和动态页面结构的网站 - 添加单个页面需要重新编译整个ES6 JavaScript模块。

[Edit 2] The concept "markup x html as data" (where markup is not only static HTML but also HTML with active components) is basic concept of whole web (every CMS has its markup data in database). [编辑2]概念“标记x html作为数据”(标记不仅是静态HTML而且是带有活动组件的HTML)是整个Web的基本概念(每个CMS在数据库中都有其标记数据)。 If there does not exist Angular2 solution for it, it denies this basic concept. 如果没有Angular2解决方案,它就会否认这个基本概念。 I believe that there must exist some trick. 我相信必须有一些技巧。

All following solutions are tricky. 以下所有解决方案都很棘手。 Official Angular team support issue is here . 官方Angular团队支持问题就在这里

Thanks to @EricMartinez for pointing me to @alexpods solution : 感谢@EricMartinez指点我@alexpods解决方案

this.laoder.loadIntoLocation(
  toComponent(template, directives), 
  this.elementRef,
  'container'
);

function toComponent(template, directives = []) {
  @Component({ selector: 'fake-component' })
  @View({ template, directives })
  class FakeComponent {}

  return FakeComponent;
}

And another similar ( from @jpleclerc ): 和另一个类似的( 来自@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
      );
    }
}

A bit different ( from @peter-svintsitskyi ): 有点不同( 来自@ 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);
        });

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM