Динамические компоненты Angular2

Я новичок в Angular2 и не нашел решения того, что пытаюсь сделать. Попробую объяснить на следующем примере.

Допустим, у нас есть родительский компонент A, который может включать дочерний компонент X или Y. Это можно легко решить с помощью viewchild.

Но что, если мы хотим динамически загружать дочерние компоненты без дублирования кода?

Реальный пример:

  • Компонент U: компонент, вызываемый пользователем, который вызывает компонент A и внедряет дочерний компонент (X или Y) в соответствии с выбором пользователя.
  • Компонент A: Контейнер сетки, который может быть таблицей, панелью или чем-то еще.
  • Компонент X: представление, содержащее строки для службы S1.
  • Компонент Y: представление, содержащее строки для службы S2.

Цель состоит в том, чтобы легко изменить контейнер, автоматически изменив все представления.

Должен быть способ сделать это, я просто не могу найти хорошее и чистое решение для такой потребности. Любая помощь приветствуется.

Спасибо


person Dave1980    schedule 28.09.2016    source источник
comment
См. Маршрутизатор компонентов Angular2. Это именно то, о чем вы просите.   -  person Technohacker    schedule 28.09.2016
comment
Все посмотрю, спасибо!   -  person Dave1980    schedule 28.09.2016
comment
@ K3v1n извините, вы говорите об основном маршрутизаторе Angular2? Если да, то я не уверен, что это именно то, что я ищу. Если нет функций, о которых я не знаю, угловой маршрутизатор должен перенаправлять запрос пользователя на компонент, а то, что я пытаюсь сделать, немного сложнее.   -  person Dave1980    schedule 29.09.2016
comment
Другой пример: допустим, у нас есть компонент A, и в его шаблоне есть что-то вроде: ‹componentX *ngIf=choice == 1 › ‹componentY *ngIf=choice == 2 › И мы хотим внедрить дочерний компонент, а не делать if , если если   -  person Dave1980    schedule 29.09.2016
comment
вы должны знать, что вы можете загрузить компонент программно: (например, this.router.navigate(["/path/of/component/route"])). Таким образом, вы можете заставить его загружать компонент в зависимости от выбора пользователя.   -  person Technohacker    schedule 29.09.2016
comment
Опять же, я не пытаюсь просто программно перейти к компоненту, я пытаюсь загрузить компонент и динамически включить его в родительский компонент, что означает внедрение дочернего компонента в родительский компонент. Во всяком случае, я обнаружил, что в предыдущих выпусках это можно было сделать с помощью DynamicComponentLoader и ComponentResolver, которые устарели в финальном выпуске.   -  person Dave1980    schedule 29.09.2016
comment
возможно, вы не заметили, что маршрутизатору Angular2 требуется <router-outlet>, чтобы знать, куда вы хотите поместить полученный загруженный компонент. Лучше оставить это как ответ   -  person Technohacker    schedule 29.09.2016


Ответы (1)


Вы можете использовать маршрутизатор компонентов Angular2 следующим образом:

(Примечание. Для простоты я не добавлял элементы ввода и вместо этого использовал элементы a. Однако применяется та же процедура, вызовите функцию, чтобы указать маршрутизатору вставить загруженный компонент в <router-outlet>)

app.component.ts

import { Component }       from '@angular/core';
import { Router }       from '@angular/router';

@Component({
    selector: 'my-app',
    template: `
        <div>
            <!-- to show how the function can be called -->
            <a href="#" (click)="load('/page1')">Page 1</a>

            <!-- Right way with links -->
            <a href="#" routerLink="/page1">Page 1</a>

            <router-outlet></router-outlet>
        </div>
    `
})
export class AppComponent {
    constructor(private router: Router)

    load(path: string): void {
        this.router.navigate([path]);
    }
}

app.routing.ts

import { ModuleWithProviders }   from '@angular/core';
import { Routes, RouterModule }  from '@angular/router';

const appRoutes: Routes = [
    {
        path: "page1",
        component: "PageOneComponent"
    }
];

export const appRoutingProviders: any[] = [

];

export const appRouting: ModuleWithProviders = RouterModule.forRoot(appRoutes);

app.module.ts

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

import { AppComponent } from './app.component';

import { appRouting, appRoutingProviders }  from './app.routing';

@NgModule({
    imports: [
        BrowserModule,
        FormsModule,
        appRouting,
    ],
    declarations: [
        RootComponent,
    ],
    providers: [
        appRoutingProviders
    ],
    bootstrap: [AppComponent]
})
export class AppModule { }

Ваше здоровье!

person Technohacker    schedule 29.09.2016
comment
Хорошо, теперь я понимаю, что вы имеете в виду. - person Dave1980; 29.09.2016
comment
В любом случае, у меня уже есть маршрутизатор, настроенный в моем приложении, и мне нужно добавить второй в свой компонент, что можно было бы назвать маршрутизаторами-выходами (‹router-outlet name=xxx›). Это может сработать. Однако использование маршрутизатора для динамического отображения дочернего компонента в родительском компоненте кажется мне скорее обходным путем, чем правильным решением. Вы не согласны? - person Dave1980; 29.09.2016
comment
Кроме того, не могли бы вы добавить компонент маршрутизатора для каждого компонента, который должен быть универсальным? Представьте себе компонент контейнера сетки, подобный следующему: шаблон: <div class="container"> <div class="panel-group"> <div class="panel panel-primary"> <div class="panel-heading">{{this.title}}</div> <div class="panel-body"> <injected-component /> </div> </div> </div> </div> В любом случае, спасибо за ваше предложение! - person Dave1980; 29.09.2016
comment
Форматирование кода комментария ужасно :P. И всегда пожалуйста! :) - person Technohacker; 29.09.2016
comment
Я согласен, что это похоже на обходной путь. но, насколько я знаю, я не видел какой-либо устоявшейся основы для ваших вещей. Роутер ближе всего к нему - person Technohacker; 29.09.2016