Presenting my demonstration application. This serves as a sample to illustrate the proper structuring for your app's functionality. While it involves calling web services, adapting it should be straightforward:
A CategoryComponent is utilized in connection with the CategoryService.
The template
<H2>Category Component</H2>
<div *ngFor="let category of categories; let ndx=index;">
<label>{{category?.name}}</label>
<input type="checkbox" id="cat.{{ndx}}" [(ngModel)]="category.selected" (change)="emitChange()">
</div>
The typescript file
import { Component, OnInit, OnDestroy } from '@angular/core';
import { CategoryService } from '../services/category.service';
import { Category } from '../models/models';
@Component({
moduleId: module.id,
selector: 'pm-category',
templateUrl: 'category.component.html',
styleUrls: ['category.component.scss']
})
export class CategoryComponent implements OnInit, OnDestroy {
private categories: Array<Category> = [];
constructor(private categoryService: CategoryService) {
}
ngOnInit() {
this.categoryService.getCategories().subscribe(list => {
if (list) {
this.categories = list;
}
});
}
ngOnDestroy() { }
private emitChange(): void {
this.categoryService.setCategories(this.categories);
}
}
Upon selecting a Category, the service gets updated.
Next up is the ProductsComponent, linking to both the CategoryService and the ProductsService while containing the ProductComponent as a child element.
The template
<H2>Products Component</H2>
<div *ngFor="let product of products; let ndx=index;">
<label>{{product?.name}}</label>
<input type="radio" name="productGroup" id="prod.{{ndx}}" value="product" (change)="setSelectedProduct(product)">
</div>
<pm-product [product]="product"></pm-product>
The typescript file
import { Component, OnInit, OnDestroy } from '@angular/core';
import { ProductsService } from '../services/products.service';
import { CategoryService } from '../services/category.service';
import { Product } from '../models/models';
@Component({
moduleId: module.id,
selector: 'pm-products',
templateUrl: 'products.component.html',
styleUrls: ['products.component.scss']
})
export class ProductsComponent implements OnInit, OnDestroy {
public product: Product;
private products: Array<Product> = [];
constructor(
private productsService: ProductsService,
private categoryService: CategoryService
) { }
ngOnInit() {
// Logic for retrieving and filtering products based on selected categories goes here
}
ngOnDestroy() { }
private setSelectedProduct(product: Product): void {
this.product = product;
}
}
Selecting a product displays its details in the ProductComponent through Input Binding between the components. Altering category selections in the CategoryComponent adjusts the list of displayed products accordingly.
Here's the ProductComponent
The template
<H2>Product Component</H2>
<div>Price: {{product?.details?.price}}</div>
<div>Age: {{product?.details?.age}}</div>
and the typescript file
import { Component, Input, OnInit, OnDestroy } from '@angular/core';
import { Product } from '../models/models';
@Component({
moduleId: module.id,
selector: 'pm-product',
templateUrl: 'product.component.html',
styleUrls: ['product.component.scss']
})
export class ProductComponent implements OnInit, OnDestroy {
@Input() product: Product;
ngOnInit() { }
ngOnDestroy() { }
}
Note that the provided sass files are empty but essential for compiling!
Included are the services and model definitions used:
The CategoryService
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable';
import { Category } from '../models/models';
@Injectable()
export class CategoryService {
// Implementation code for handling categories
}
The ProductsService
import { Injectable } from '@angular/core';
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import { Observable } from 'rxjs/Observable';
import { Product, Details } from '../models/models';
@Injectable()
export class ProductsService {
// Implementation code for managing products
}
Models defined in models.ts
export class Category {
// Definition for Category object
}
export class Details {
// Definition for Details object
}
export class Product {
// Definition for Product object
}
MainPageModule setup for integration into the larger app structure.
import { NgModule } from '@angular/core';
// Import statements
@NgModule({
imports: [
// Module imports
],
declarations: [
// Components declaration
],
exports: [
// Component exports
],
providers: [
// Services inclusion
]
})
export class MainPageModule {
}
Combining these segments results in a basic functioning app mirroring your outlined requirements. It aims as a demo for illustrative purposes. :)