简体   繁体   中英

how to generate dynamic menu and components in angular based on API response

I want to (propably) dynamically generate some number of menu positions and components reffering to these menu positions based on API response. Response to c# backend would be made on application start in app.component.ts. Those menu positions would be statuses of proceesing items (for example "finished", "in progress" etc.) and html in every component should look almost identically (just table with positions from sql database, only difference between them was sql query made to database with different "where" clause). Now it is two statuses, but in future it could be 7 more, so I don't want to create a new component in angular every time I add new status in backend. So what I should be looking for? And after receiving response from api where should I store this answer? (In order to have those components all time, I don't want them to dissapear after page reload or anything else).

When displaying data fetched from an API it's good practice to implement a model controller view pattern where the date is downloaded by the controller (a service), saved in the model which is marked with the @Injectable() decortator and is injected in the view component you're displaying the data. So your fetched data is stored in the model and can be accessed everywhere you need it.

The controller can look something like that:

@Injectable({
    providedIn: 'root'
})
export class StatusService{
    constructor(private http : HttpClient) 
    { }

    public getStatus() : Observable<any>
    {
        return this.http.get('http://myapi.com/getstatus');    
    }
}

The model is just storing this data:

export class Status
{
    public id : number;
    public type: string;
}

@Injectable()
export class StatusModel
{
    public statuses: Status[];

    constructor(private statusService : StatusService) 
    { }

    public getStatus() : Observable<Status[]>
    {
        return this.statusService.getstatus().pipe(map((status: Status[]) => 
        {
            this.statuses = data;
            return this.statuses ;
        }));
    }
}

In you component (view) you're injecting the StatusModel in the constructor and make the API request:

@Component({
    selector: 'app-status',
    templateUrl: './status.component.html',
    styleUrls: ['./status.component.scss'],
})
export class StatusComponent implements OnInit {
    constructor(public statusModel : StatusModel)
    {
        this.getStatus();
    }

public getStatus() : void
    {
        this.statusModel.getStatus().subscribe(
            (data) => 
            {
                console.log(data);
            },
            (error) =>
            {
                console.log(error);
            }
        );
    }
}

In your HTML you can dispay these statuses stored in statusModel.statuses using *ngFor like that:

<div class="status" *ngFor="let status of statusModel.statuses">
    <p>{{status.id}</p>
    <p>{{status.type}}</p>
</div>

You can also use *ngIf to display different statuses differently or ngClass to set specific style classes for specific statuses.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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