Angular7-Appcomponent中的访问参数

时间:2019-05-06 13:53:26

标签: html angular typescript

我的应用程序需要品牌代码来确定样式和dom。

当前加载的URL为www.SiteName.com/HBL(HBL = brandName)

这是一个简单的网站,其中只有页眉,页脚和搜索组件。

但是我需要从服务api获取品牌信息。

因此,在Appcomponent.ts中,我注入了ActivatedRoute,在ngOnInit方法中,我订阅了paramMap。

加载应用程序时,我得到的参数值为空。

这是我所做的

我的app.compnent.html:

<div class="container">
  <header [brand]="brand"></header>
  <!-- <esw-search></esw-search> -->
  <router-outlet></router-outlet> - Search will be populated thru route 
  <esw-footer></esw-footer>
</div>

本来可以避免使用路由器,但是有时可以直接访问搜索页面。

例如www.SiteName.com/HBL/search?trackingnumber=123456;language=zh-CN

我的路由组件:

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

import { NotFoundComponent } from './notfound/notfound.component';
import { SearchComponent } from './tracking-search/search/search.component';

const routes: Routes = [
  { path: '', component: SearchComponent },
  { path: ':brandName/search', component: SearchComponent },
  { path: ':brandName/', component: SearchComponent },
  { path: '404', component: NotFoundComponent },
  { path: '**', redirectTo: '404' }
];
@NgModule({
  imports: [RouterModule.forRoot(routes)],
  exports: [RouterModule]
})

export class AppRoutingModule { }

我的appcomponent.ts代码:

@Component({
  selector: 'esw-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss']
})
export class AppComponent implements OnInit {
  title = 'logistics-tracking-ui';
  apiUrl: string;
  brand: Brand;

  constructor(
    private tracking: TrackingService,
    private route: ActivatedRoute) {
  }

  ngOnInit(): void {

    this.route.paramMap.subscribe(params => {
      const brandName = params.get('brandName');
      this.tracking.getBrandData(brandName).subscribe((response) => this.brand = response);
    });
  }
  }
}

SearchComponent.htm:

<div class="card-body">

  <div class="card mx-auto">
    <div class="card-body">
      <h3 style=" text-align: center"> Track your International Package</h3>
      <div>
        <span class="ui-float-label">
          <input [(ngModel)]="trackingNumber" id="float-input" type="text" size="30" pInputText>

          <label for="float-input">Tracking Number</label>

        </span>
        <button pButton type="button" label="Click" (click)="searchTracking()"></button>
      </div>
      <esw-search-details [trackingDetails]='trackingDetails$'></esw-search-details>
    </div>
  </div>

</div>

searchComponent.ts:

@Component({
  selector: 'esw-search',
  templateUrl: './search.component.html',
  styleUrls: ['./search.component.scss']
})
export class SearchComponent implements OnInit {
  trackingNumber = '';
  trackingDetails$: Observable<any>;

  constructor(private trackingservice: TrackingService) { }

  ngOnInit() {
  }

  searchTracking(): void {
    alert('Search Clicked' + this.trackingNumber);
    if (!this.trackingNumber.trim()) {
      // if not search term, return empty hero array.
      // Publish error message
      console.log('Invalid Input');
      return;
    }

    this.trackingDetails$ = this.trackingservice.getTrackingDetails(this.trackingNumber, 'en-GB');


  }

注意:我没有为search&serachDetails组件添加太多逻辑。

问题在于我

  1. 访问App组件中的品牌参数值。
  2. 在app.coponent.html中定义布局的这种方法正确吗?
  3. 有什么更好的方法可以使用吗?

对不起,这是我的第一个有角度的项目,我们将为您提供任何帮助。

2 个答案:

答案 0 :(得分:0)

也许您需要为参数添加一条路线,并且必须将其添加为路线列表中的第一条路线,例如

const routes: Routes = [
  { path: ':brandName/:brand', component: SearchComponent },
  { path: ':brandName/search', component: SearchComponent },
  { path: ':brandName/', component: SearchComponent },
  { path: '404', component: NotFoundComponent }, 
  { path: '', component: SearchComponent },
 { path: '**', redirectTo: '404' }
];

,现在在应用程序组件中,我们可以像这样访问它:-

 this.route.paramMap.subscribe(params => {
      const brandName = params['brand']
      this.tracking.getBrandData(brandName).subscribe((response) => this.brand = response);
    });

答案 1 :(得分:0)

如果要通过导出/导入操作,则必须注意异步加载JS。假设您的api调用,导出和导入设置正确,Api调用完成,并且在加载标头组件后填充品牌((在api调用完成后,通过在应用程序组件中添加控制台日志进行验证。加载标头后将看到它的日志,这使得标头组件的ngOnInit方法无法访问它)。因此,您可以阻止加载,直到拥有必需的元素为止:

<header *ngIf="ReturnedObject.brand" [brand]="brand"></header>

或者您也可以在页面加载了Ng生命周期挂钩之后加载元素,例如

ngAfterContentInit(){}

(这不是一个很好的选择,因为您的页面会以任何默认品牌加载,然后在品牌更新后重新加载)

我的首选方法

您可以根据需要使用“ {{}}”表示法来动态命名元素的类,而不是通过导出导出来加载另一个组件,而是在父组件中设置该类,然后加载子组件:

(在您的孩子的CSS中)

.texas {
background-image: texasFlag.png;
}
 .newYork {
background-image: newYorkFlag.png;
}

(在您的父HTML中)

<header class="{{ReturnedObject.brand}}"></header>
<your-child-component></your-child-component>
<footer class="{{ReturnedObject.brand}}"></footer>

那样,父级已经在孩子开始加载之前设置了该类,从而消除了父级和子级组件正在加载的“竞赛”。