2016-03-15 26 views
11

Tôi đang chuẩn bị trang web SPA chứa hàng trăm trang giống như bài viết (ngoài thương mại điện tử, đăng nhập, v.v.). Mỗi bài viết đều có URL riêng. Tôi muốn nhận ra nó bằng cách sử dụng Angular2. Giải pháp duy nhất tôi tìm thấy cho đến nay là:Làm thế nào để nhận ra trang web với hàng trăm trang trong Angular2

1. để chuẩn bị hàng trăm thành phần Agular2, một thành phần cho mỗi bài viết ...

... với templateUrl trỏ đến đánh dấu bài viết. Vì vậy, tôi sẽ cần hàng trăm thành phần tương tự như:

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

2. để hiển thị một bài báo sử dụng AsyncRoute

thấy 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 { } 

Trong Angular1 đã có chỉ thị ngInclude, mà là mất tích trong Angular2 do các vấn đề an ninh (xem here).

[Chỉnh sửa 1] Không chỉ có vấn đề với chính mã đó. Vấn đề cũng là với tính chất tĩnh của giải pháp này. Nếu tôi cần trang web với sơ đồ trang web và cấu trúc trang động - việc thêm một trang cần biên dịch lại toàn bộ mô-đun JavaScript của ES6.

[Chỉnh sửa 2] Khái niệm "đánh dấu x html dưới dạng dữ liệu" (nơi đánh dấu không chỉ HTML tĩnh mà còn HTML với các thành phần hoạt động) là khái niệm cơ bản của toàn bộ web (mỗi CMS có dữ liệu đánh dấu trong cơ sở dữ liệu). Nếu không tồn tại giải pháp Angular2 cho nó, nó phủ nhận khái niệm cơ bản này. Tôi tin rằng phải tồn tại một số mẹo.

+0

Vì vậy, đây là tất cả về việc thiếu hỗ trợ liên kết với các mẫu do người dùng cung cấp, đúng không? –

+0

Tôi bối rối với điểm của câu hỏi này. Vì vậy, nếu bạn có tuyến đường '/ articles/articleId' và bạn thực hiện yêu cầu để nhận nội dung cụ thể đó bằng Id, tại sao bạn cần tất cả các trang tĩnh? Để không nói về kích thước javascript của bạn sẽ nhận được. –

+0

Gunter: Đúng vậy. Tương tự như ngInclude trong Angular1. Joel: Thật kỳ lạ, có vẻ như Angular2 không cho phép kịch bản "Content by Id". Tất cả nội dung phải được bao bọc bởi thành phần (được xác định tĩnh trong mã). –

Trả lời

6

Tất cả các giải pháp sau đều phức tạp. Vấn đề hỗ trợ nhóm chính thức của Angular là here.

Nhờ @EricMartinez chỉ cho tôi đến @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; 
} 

Và khác tương tự (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 
    ); 
    } 
} 

Một chút khác nhau (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); 
     }); 
+0

+1 cho câu trả lời này bởi vì nó được liên kết từ câu trả lời này: http://stackoverflow.com/a/37994020/1175496, đó là tất cả về lý do 'nền tảng trình duyệt' so với 'plastform-browser-dynamic' ; là thứ sau cần thiết để làm điều này? –

Các vấn đề liên quan