Angular - 在多个组件中包含 html 的最佳方法是什么?
Angular - What's the best way to include html in multiple components?
我需要在项目的多个组件中加载。因此,与其在组件之间一遍又一遍地放置相同的 HTML,我需要知道不重复代码的最佳方法是什么,但我不知道这样做是否正确。我创建了一个名为 loading-graphic
的组件,我将其绑定到各个组件的每个 HTML 文件中。我阅读了 ngTemplateOutlet
和 ngContent
,但老实说,在我的脑海中将它用于这种情况没有任何意义(而且我也不明白......我是初学者就可以了)。那么,我应该赌什么?谢谢。
我认为加载组件是个不错的主意。在您的应用程序根组件中使用加载组件。您可以使用 loading.service 和拦截器来显示或隐藏组件。对于每个 API 调用,您将自动获得一个加载指示器。
示例:https://medium.com/@zeljkoradic/loader-bar-on-every-http-request-in-angular-6-60d8572a21a9
根据您的问题,我认为使用 NgTemplateOutlet 创建可重用组件是避免在不同组件模板中重复 HTML 的最佳解决方案。它允许您根据主机组件传递参数,并使您的 Angular 应用程序更易于测试和开发,因为它放慢了针对各种用例的易于修改的可重用组件,而无需修改单个组件本身。
由于您是初学者,我将举例说明使用 NgTemplateOutlet 的简单方法,但稍后会深入探讨模板和图章。
假设您有一个可重用的搜索组件,您希望在其中隐藏基于父组件的复选框。您的模板将如下所示。
我们使用@Input 和属性 绑定将数据从父组件传递到child/Search 组件,因此我们根据父组件定义隐藏哪些复选框。
这是搜索组件的代码示例
search.component.ts
======================
import { Component, OnInit, Output, EventEmitter, Input } from '@angular/core';
@Component({
selector: 'app-search',
templateUrl: './app-search.component.html',
styleUrls: ['./app-search.component.css']
})
export class AppSearchComponent implements OnInit {
accountName: string = '';
@Output() accountSearchChange = new EventEmitter<string>(); //1. Event Binding to pass data from Child to Parent Component ->Int
@Input() searchMode: 'account' | 'holder' | 'distribution' = 'account'; //Use NgTemplateOutlet for reusable componenet
constructor() { }
ngOnInit() {
}
//2. Event Binding to pass data from Child to Parent Component ->Invoke Emit
doSearchFilter(searchText: string) {
console.log('Search Child: doSearchFilter -> ' + searchText);
this.accountSearchChange.emit(searchText);
}
clearFilters() {
console.log('Account Search: Clear Filter is called');
this.accountName = '';
}
}
search.component.html
=====================
<ng-container [ngSwitch]="searchMode">
<div class="input-full-width" *ngSwitchCase="'account'">
<mat-checkbox class="example-container check-full-width">Show active and pending only</mat-checkbox>
</div>
<div class="input-full-width" *ngSwitchCase="'holder'">
<mat-checkbox class="example-container check-full-width">View only holders with missing requirements</mat-checkbox>
</div>
<div class="input-full-width" *ngSwitchCase="'holder'">
<mat-checkbox class="example-container check-full-width">View only active Holders</mat-checkbox>
</div>
</ng-container>
我在帐户组件中使用搜索组件,下面是代码示例。
在 HTML 文件中,我指的是 app-search css 选择器并传递 ts 中定义的搜索模式。
import { Component, OnInit, ViewChild, AfterViewInit } from '@angular/core';
import { MatSort, MatTableDataSource, MatPaginator } from '@angular/material';
import { Router } from "@angular/router";
import { Observable } from 'rxjs';
import { AccountService } from 'src/app/core/services/account.service';
import { Deal } from 'src/app/core/models/deal';
@Component({
selector: 'app-account',
templateUrl: './account.component.html',
styleUrls: ['./account.component.css']
})
export class AccountsComponent implements OnInit, AfterViewInit {
displayedColumns: string[] = ['accountId', 'accountShortName', 'accountType'];
public dealDataSource = new MatTableDataSource<Deal>();
dealsObservable: Observable<Deal[]>;
searchMode = 'distribution';
isLoadingResults = true;
@ViewChild(MatSort) sort: MatSort;
@ViewChild(MatPaginator) paginator: MatPaginator;
constructor(private router: Router, private api: AccountService) { }
......................................................
<app-search (accountSearchChange)='doFilter($event)' [searchMode]="searchMode"></app-search>
希望这是清楚的。
我需要在项目的多个组件中加载。因此,与其在组件之间一遍又一遍地放置相同的 HTML,我需要知道不重复代码的最佳方法是什么,但我不知道这样做是否正确。我创建了一个名为 loading-graphic
的组件,我将其绑定到各个组件的每个 HTML 文件中。我阅读了 ngTemplateOutlet
和 ngContent
,但老实说,在我的脑海中将它用于这种情况没有任何意义(而且我也不明白......我是初学者就可以了)。那么,我应该赌什么?谢谢。
我认为加载组件是个不错的主意。在您的应用程序根组件中使用加载组件。您可以使用 loading.service 和拦截器来显示或隐藏组件。对于每个 API 调用,您将自动获得一个加载指示器。
示例:https://medium.com/@zeljkoradic/loader-bar-on-every-http-request-in-angular-6-60d8572a21a9
根据您的问题,我认为使用 NgTemplateOutlet 创建可重用组件是避免在不同组件模板中重复 HTML 的最佳解决方案。它允许您根据主机组件传递参数,并使您的 Angular 应用程序更易于测试和开发,因为它放慢了针对各种用例的易于修改的可重用组件,而无需修改单个组件本身。
由于您是初学者,我将举例说明使用 NgTemplateOutlet 的简单方法,但稍后会深入探讨模板和图章。
假设您有一个可重用的搜索组件,您希望在其中隐藏基于父组件的复选框。您的模板将如下所示。
我们使用@Input 和属性 绑定将数据从父组件传递到child/Search 组件,因此我们根据父组件定义隐藏哪些复选框。
这是搜索组件的代码示例
search.component.ts
======================
import { Component, OnInit, Output, EventEmitter, Input } from '@angular/core';
@Component({
selector: 'app-search',
templateUrl: './app-search.component.html',
styleUrls: ['./app-search.component.css']
})
export class AppSearchComponent implements OnInit {
accountName: string = '';
@Output() accountSearchChange = new EventEmitter<string>(); //1. Event Binding to pass data from Child to Parent Component ->Int
@Input() searchMode: 'account' | 'holder' | 'distribution' = 'account'; //Use NgTemplateOutlet for reusable componenet
constructor() { }
ngOnInit() {
}
//2. Event Binding to pass data from Child to Parent Component ->Invoke Emit
doSearchFilter(searchText: string) {
console.log('Search Child: doSearchFilter -> ' + searchText);
this.accountSearchChange.emit(searchText);
}
clearFilters() {
console.log('Account Search: Clear Filter is called');
this.accountName = '';
}
}
search.component.html
=====================
<ng-container [ngSwitch]="searchMode">
<div class="input-full-width" *ngSwitchCase="'account'">
<mat-checkbox class="example-container check-full-width">Show active and pending only</mat-checkbox>
</div>
<div class="input-full-width" *ngSwitchCase="'holder'">
<mat-checkbox class="example-container check-full-width">View only holders with missing requirements</mat-checkbox>
</div>
<div class="input-full-width" *ngSwitchCase="'holder'">
<mat-checkbox class="example-container check-full-width">View only active Holders</mat-checkbox>
</div>
</ng-container>
我在帐户组件中使用搜索组件,下面是代码示例。 在 HTML 文件中,我指的是 app-search css 选择器并传递 ts 中定义的搜索模式。
import { Component, OnInit, ViewChild, AfterViewInit } from '@angular/core';
import { MatSort, MatTableDataSource, MatPaginator } from '@angular/material';
import { Router } from "@angular/router";
import { Observable } from 'rxjs';
import { AccountService } from 'src/app/core/services/account.service';
import { Deal } from 'src/app/core/models/deal';
@Component({
selector: 'app-account',
templateUrl: './account.component.html',
styleUrls: ['./account.component.css']
})
export class AccountsComponent implements OnInit, AfterViewInit {
displayedColumns: string[] = ['accountId', 'accountShortName', 'accountType'];
public dealDataSource = new MatTableDataSource<Deal>();
dealsObservable: Observable<Deal[]>;
searchMode = 'distribution';
isLoadingResults = true;
@ViewChild(MatSort) sort: MatSort;
@ViewChild(MatPaginator) paginator: MatPaginator;
constructor(private router: Router, private api: AccountService) { }
......................................................
<app-search (accountSearchChange)='doFilter($event)' [searchMode]="searchMode"></app-search>
希望这是清楚的。