возврат к дочернему компоненту не дает результата при первом нажатии [угловой] [наблюдаемый] - PullRequest
0 голосов
/ 02 августа 2020

Мой родительский компонент: html:

<div class="oil-wrapper container">
    <div class="oil-header">
      <span class="oil-header__category">Категории</span>
      <span class="oil-header__selected-name">{{ this.selectedCategoryNameToShow }}</span>
    </div>
    <div class="content-container container">
      <aside class="navigation-container">
        <mat-accordion>
          <mat-expansion-panel
            [id]="category._id.$oid"
            *ngFor="let category of categoryList"
            (click)="selectCategory(category)"
            [ngClass]="{'active': category.activeClass}"
            [expanded]="category.isExpanded"
            routerLink="/products/oil"
            routerLinkActive="list-item-active"
          >

            <mat-expansion-panel-header>
              <mat-panel-title>
                {{ category.name }}
              </mat-panel-title>
            </mat-expansion-panel-header>

            <div
              class="expansion-item sub-categories-item"
              [id]="subcategory.sub_id.$oid"
              *ngFor="let subcategory of category.subCategories"
              [ngClass]="{'active': subcategory.activeClass}"
              routerLink="/products/oil"
              routerLinkActive="list-item-active"
              (click)="$event.stopPropagation(); selectSubCategory(subcategory, category.subCategories)">
              {{subcategory.name}}
            </div>
            <div class="sub-categories">
            </div>

          </mat-expansion-panel>
        </mat-accordion>
      </aside>
      <section class="product-wrapper">
        <router-outlet></router-outlet>
      </section>
    </div>
  </div>

ts:

constructor(
    private categoryService: CategoryService,
    private brandService: BrandService,
    private productOilService: ProductOilService,
    private dataService: DataService,
  ) {

  }

  ngOnInit(): void {
    this.getCategoryList();
    this.getProductsOilList();
  }

  getCategoryList() {
    this.categoryService.getAll()
      .subscribe(categoryList => {
        this.categoryList = categoryList;
        this.categoryList.push(this.brandCategory);

        this.brandService.getAll()
          .subscribe(brandList => {
            this.brandList = brandList;
            this.brandList.map((el) => {
              el.sub_id = el._id;
            });
            this.categoryList[this.categoryList.length - 1].subCategories = this.brandList;
          });
      });
  }

  getProductsOilList() {
    this.productOilService.getAll()
      .subscribe(productsOilList => {
        this.productsOilList = productsOilList;
        this.productsToShow = this.productsOilList;
        this.dataService.showProducts(this.productsToShow);
      });
  }

  selectCategory(item) {
    const expansionDOM = document.getElementById(item._id.$oid);
    const isExpanded = expansionDOM.classList.contains('mat-expanded');

    item.isExpanded = true;

    if (item.subCategories) {
      item.subCategories.forEach(el => {
        el.activeClass = false;
      });
    }

    if (this.selectedCategory === item.name && !isExpanded) {
      this.productsToShow = this.productsOilList;
      this.selectedCategoryNameToShow = 'Все продукты';
    } else {
      this.selectedCategory = item.name;
      this.selectedCategoryNameToShow = item.name;
      this.productsToShow = this.productsOilList;
      if (!item.isBrand) {
        this.productsToShow = this.productsToShow.filter((el) => {
          return el.category._id.$oid === item._id.$oid;
        });
      }
    }

    this.dataService.showProducts(this.productsToShow);
  }

  selectSubCategory(subcategory, list) {
    list.forEach(el => {
      el.activeClass = false;
    });

    subcategory.activeClass = true;
    this.selectedCategoryNameToShow = subcategory.name;
    this.productsToShow = this.productsOilList;
    this.productsToShow = this.productsToShow.filter((el) => {
      if (el.subcategory !== 'null') {
        return el.subcategory.sub_id.$oid === subcategory.sub_id.$oid || el.brand._id.$oid === subcategory.sub_id.$oid;
      }
    });

    this.dataService.showProducts(this.productsToShow);
  }

дочерний компонент ProductsOilListComponent: html:

<div class="product-container">
  <mat-card class="product-item" *ngFor="let product of productsToShow | slice: (page-1) * pageSize : (page-1) * pageSize + pageSize">
    <img [src]="env.serverURL + product.imgPath" class="product-img" alt="">
    <div class="product-title-desc-container">
      <mat-card-header>
        <mat-card-title>{{product.name}}</mat-card-title>
      </mat-card-header>
      <mat-card-content [innerHTML]="product.description | slice : 0 : 185" class="description"></mat-card-content>
    </div>
    <mat-card-actions class="button-container">
      <button mat-flat-button class="price">Запросить цену</button>
      <a
        mat-flat-button
        class="more"
        routerLink="/products/oil/{{product.slug}}"
      >Подробнее</a>
    </mat-card-actions>
  </mat-card>
  <div *ngIf="productsToShow.length === 0">В этой категории продукты не представлены</div>
</div>
<div class="pagination-block">
  <ngb-pagination
    [(page)]="page"
    [pageSize]="pageSize"
    [collectionSize]="productsToShow.length">
  </ngb-pagination>
</div>

ts:

  export class ProductsOilListComponent implements OnDestroy {

  productsToShow = [];
  subscription: Subscription;
  public env = environment;
  public page = 1;
  public pageSize = 5;

  constructor(
    private productOilService: ProductOilService,
    private dataService: DataService,
  ) {
    console.log('child-component');

    this.subscription = dataService.showProducts$.subscribe(products => {
      this.productsToShow = products;
    });
  }

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

второй дочерний компонент ProductsOilItemComponent: html:

<div class="product-item">
  <div class="product-item__img">
    <img [src]="env.serverURL + product.imgPath" alt="">
  </div>
  <mat-tab-group>
    <mat-tab label="Описание">
      <div class="product-item__description">
        <span class="text" [innerHTML]="product.description"></span>
        <div class="button-container">
          <button mat-raised-button class=" button-container__consult1-btn">
            <mat-icon aria-hidden="true" class="md-18">file_download</mat-icon>
            Тех. описание
          </button>
          <button mat-raised-button class=" button-container__consult2-btn">
            <mat-icon aria-hidden="true">file_download</mat-icon>
            Паспорт качества
          </button>
          <button mat-flat-button class=" button-container__consult-btn">Заказать</button>
        </div>
      </div>
    </mat-tab>
    <mat-tab label="Характеристики">
      <div class="product-bottom__spec">
        <span class="text" [innerHTML]="product.spec"></span>
      </div>
    </mat-tab>
  </mat-tab-group>
</div>

ts:

export class ProductsOilItemComponent implements OnInit {

  public env = environment;
  public productsToShow = [];
  public subscriptions = new Subscription();
  public product = {
    imgPath: '',
    name: '',
    description: '',
    spec: '',
    pdf1Path: '',
    pdf2Path: '',
    pdf1Name: '',
    pdf2Name: ''
  };

  constructor(
    private productOilService: ProductOilService,
    private dataService: DataService,
  ) {
  }

  ngOnInit(): void {
    this.getProductBySlug();

  }

  getProductBySlug() {
    const slug = document.location.pathname.split('/');
    const data = {slug: slug[slug.length - 1]};
    this.productOilService.getProductBySlug(data)
      .subscribe(product => {
        this.product = product[0];
        this.product.pdf1Name = this.getPdfNameFromPath(this.product.pdf1Path);
        this.product.pdf2Name = this.getPdfNameFromPath(this.product.pdf2Path);
      });
  }

  getPdfNameFromPath(path) {
    return path.replace(this.env.pdfFilePath, '');
  }
}

data.service:

import {Injectable} from '@angular/core';
import {Subject} from 'rxjs';

@Injectable({providedIn: 'root'})
export class DataService {

  constructor() {
  }

  private productsToShow = new Subject<Array<any>>();
  public showProducts$ = this.productsToShow.asObservable();

  // Service message commands
  showProducts(products: any[]) {
    this.productsToShow.next(products);
  }
}

Маршруты:

const routes: Routes = [
  {
    path: '', component: HomeComponent, children: [
      {path: '', component: MainComponent},
      {path: 'catalogs', component: CatalogsHomeComponent},
      {path: 'products', component: ProductsComponent},
      {path: 'products/oil', component: ProductsOilHomeComponent, children: [
          {path: '', component: ProductsOilListComponent},
          {path: ':slug', component: ProductsOilItemComponent},
        ]},
      {path: 'products/drill', component: ProductsDrillHomeComponent},
      {path: 'products/drill/:slug', component: ProductsDrillItemComponent},
      {path: 'news', component: NewsHomeComponent},
      {path: 'about', component: AboutComponent},
      {path: 'login', component: LoginComponent},
      {path: 'register', component: RegisterComponent},
    ]
  },

  {
    path: 'admin', component: AdminComponent, canActivate: [AuthGuard], children: [
      {path: '', component: DashboardComponent},
      {path: 'news', component: NewsComponent},
      {path: 'brands', component: BrandsComponent},
      {path: 'catalogs', component: CatalogsComponent},
      {path: 'categories', component: CategoriesComponent},
      {path: 'categories/add', component: CategoriesEditComponent},
      {path: 'categories/edit/:id', component: CategoriesEditComponent},
      {path: 'products-oil', component: ProductsOilComponent},
      {path: 'products-drill', component: ProductsDrillComponent},
    ]
  },
  // otherwise redirect to home
  // {path: '**', redirectTo: ''}
];

Проблема: когда я перехожу на страницу «продукт / масло» извне, например из «продукта», у меня хорошие результаты отображаются в дочернем компоненте ProductsOilListComponent.

После того, как я go перехожу к ProductsOilItemComponent и щелкаю назад, чтобы перейти к «продукту / маслу» в боковом разделе, список продуктов не отображается. Полагаю, мне нужно как-то снова запустить наблюдаемый объект, но я не знаю, как это сделать.

PS: когда я дважды щелкаю по той же ссылке в боковом секторе, я получил ожидаемый результат. Но есть ли способы отобразить список товаров с первого щелчка?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...