quartaela
quartaela

Reputation: 2757

angular component - how to avoid having nested components

Hi I am learning angular and I have a question about components. I have two components one root and one other. When I go from root to other one I will see the contents from root controller. It looks like angular creates child components which makes child components to keep content from parent. But how can I display a totally new template? Here is the two controller I have. I can also verify that from html page created second component is getting created under root component's section.

This is the root controller.

market-data.component.ts

import { Component, OnInit, Inject } from "@angular/core";
import { MarketDataService } from "./market-data.service";
import { CoinMarketCapTokenEntity } from "../entity/coinmarketcaptoken-entity";

@Component({
    selector: "app-market-data",
    templateUrl: "./src/app/market-data.component.html"
})
export class MarketDataComponent implements OnInit {
    private _marketDataService: MarketDataService;
    private tokens: any;

    constructor(marketDataService: MarketDataService) {
        this._marketDataService = marketDataService;
    }

    ngOnInit() {
        /*this._marketDataService.getCoinMarketCapTokens()
            .subscribe(res => this.tokens = res);*/
        this.tokens = [
            {
                symbol: "BTC"
            },
            {
                symbol: "ETH"
            }
        ];
    }
}

market-data.component.html

<table class="table table-sm table-hover">
    <thead>
        <tr>
            <th scope="col">Symbol</th>
        </tr>
    </thead>
    <tbody>
        <tr *ngFor="let token of tokens">
            <td>
                <a [routerLink]="['/marketData', token.symbol]">
                    {{ token.symbol }}
                </a>
            </td>
        </tr>
    </tbody>
</table>
<router-outlet></router-outlet>

And here is the second (child) component

kline.component.ts

import { Component, Input, OnInit, OnDestroy } from "@angular/core";
import { ActivatedRoute, Router } from "@angular/router";
import { MarketDataService } from "./market-data.service";

@Component({
    selector: "app-kline",
    template: `
        <section *ngIf="currentSymbol">
            <h2>You selected: {{ currentSymbol }}</h2>
        </section>

        <!-- New Button Here -->
        <button (click)="goToMarketDataList()">Back to Market Data List</button>
    `
})
export class KLineComponent implements OnInit, OnDestroy {
    private marketDataService: MarketDataService;
    private route: ActivatedRoute;
    private router: Router;
    private sub: any;

    // bind symbol here
    @Input() currentSymbol: string;

    constructor(marketDataService: MarketDataService,
                route: ActivatedRoute,
                router: Router) {
        this.marketDataService = marketDataService;
        this.route = route;
        this.router = router;
    }

    ngOnInit() {
        this.sub = this.route.params.subscribe(params => {
            let symbol = params["market"];
            //this.currentSymbol = this.marketDataService.getToken(symbol).symbol;
            this.currentSymbol = "BTC";
        });
    }

    ngOnDestroy(): void {
        this.sub.unsubscribe();
    }

    goToMarketDataList() {
        let link = ["/"];
        this.router.navigate(link);
    }
}

app.module.ts

import { NgModule } from "@angular/core";
import { BrowserModule } from "@angular/platform-browser";
import { FormsModule } from "@angular/forms";
import { HttpClientModule } from "@angular/common/http";

import { MarketDataComponent } from "./app/market-data.component";
import { MarketDataService } from "./app/market-data.service";
import { KLineComponent } from "./app/kline.component";

import { appRouterModule } from "./app.routes";

@NgModule({
    imports: [
        BrowserModule,
        FormsModule,
        HttpClientModule,
        appRouterModule
    ],
    declarations: [
        MarketDataComponent,
        KLineComponent
    ],
    bootstrap: [
        MarketDataComponent
    ],
    providers: [
        MarketDataService
    ]
})
export class AppModule {}

And routes config if it helps.

app.routes.ts

import { Routes, RouterModule } from "@angular/router";
import { MarketDataComponent } from "./app/market-data.component";
import { KLineComponent } from "./app/kline.component";

const routes: Routes = [
    {
        path: "marketData/:market",
        component: KLineComponent
    }
];

export const appRouterModule = RouterModule.forRoot(routes);

Upvotes: 0

Views: 691

Answers (1)

Akshay Rana
Akshay Rana

Reputation: 1485

This is because you have <router-outlet> in your root component. All the components that get rendered via routing will be loaded inside the <router-outlet>.

What you should do is, put only <router-outlet></router-outlet> in the template of root component say AppComponent, and create a different component for MarketDataComponent, and add a route for that too.

You can add a default route like:

{
    path: "",
    component: MarketDataComponent
},
{
    path: "marketData/:market",
    component: KLineComponent
}

So, by default, when there is no route but only "/", MarketDataComponent will be first loaded in the router-outlet of AppComponent, and after navigation to KLineComponent, it will be loaded in the router-outlet of AppComponent again replacing the MArketDataComponent.

Upvotes: 2

Related Questions