面试题答案
一键面试1. 数据绑定方式
在Angular中,对于商品信息展示,主要使用以下几种数据绑定方式:
- 插值表达式:用于在模板中显示数据,例如
{{product.price}}
。 - 属性绑定:当需要动态设置HTML元素属性时使用,比如根据库存显示不同的样式:
<div [class.out - of - stock]="product.stock === 0">...</div>
。 - 事件绑定:用于处理用户操作,如筛选和排序按钮的点击事件,
<button (click)="sortProducts('price')">按价格排序</button>
。
2. 变化检测机制
Angular默认使用Zone.js来检测变化。Zone.js会拦截异步操作(如HTTP请求、定时器等),当这些异步操作完成时,Angular会检查组件树中所有组件的数据变化,并更新视图。对于复杂场景,若需要手动触发变化检测,可以注入 ChangeDetectorRef
并调用 detectChanges()
方法。
3. 处理数据的实时更新
- HTTP轮询:可以定期通过HTTP请求获取最新数据,在服务中使用
interval
和switchMap
实现轮询:
import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { interval } from 'rxjs';
import { switchMap } from 'rxjs/operators';
@Injectable({
providedIn: 'root'
})
export class ProductService {
constructor(private http: HttpClient) {}
getProducts() {
return interval(5000).pipe( // 每5秒请求一次
switchMap(() => this.http.get('/api/products'))
);
}
}
- WebSocket:更适合实时更新场景,使用
@stomp/stompjs
库:
import { Injectable } from '@angular/core';
import * as Stomp from '@stomp/stompjs';
import * as SockJS from'sockjs - client';
import { Observable } from 'rxjs';
@Injectable({
providedIn: 'root'
})
export class WebSocketService {
private stompClient: any;
constructor() {}
connect() {
const socket = new SockJS('/websocket - endpoint');
this.stompClient = Stomp.over(socket);
const that = this;
return new Observable((observer) => {
this.stompClient.connect({}, function(frame) {
that.stompClient.subscribe('/topic/products', function(product) {
observer.next(JSON.parse(product.body));
});
}, function(error) {
observer.error(error);
});
});
}
}
4. 完整代码架构
- 组件结构:
src/
├── app/
│ ├── product - list/
│ │ ├── product - list.component.ts
│ │ ├── product - list.component.html
│ │ ├── product - list.component.css
│ │ └── product - list.component.spec.ts
│ ├── product - service.ts
│ ├── app.component.ts
│ ├── app.component.html
│ ├── app.component.css
│ └── app.module.ts
- 关键代码片段:
- product - list.component.ts
import { Component, OnInit } from '@angular/core';
import { ProductService } from '../product - service';
import { WebSocketService } from '../web - socket.service';
@Component({
selector: 'app - product - list',
templateUrl: './product - list.component.html',
styleUrls: ['./product - list.component.css']
})
export class ProductListComponent implements OnInit {
products: any[] = [];
constructor(private productService: ProductService, private webSocketService: WebSocketService) {}
ngOnInit() {
// 使用HTTP轮询获取数据
this.productService.getProducts().subscribe((products) => {
this.products = products;
});
// 使用WebSocket实时更新数据
this.webSocketService.connect().subscribe((product) => {
const index = this.products.findIndex(p => p.id === product.id);
if (index!== -1) {
this.products[index] = product;
} else {
this.products.push(product);
}
});
}
sortProducts(field: string) {
this.products.sort((a, b) => {
if (field === 'price') {
return a.price - b.price;
}
// 其他排序逻辑
return 0;
});
}
filterProducts(filter: string) {
// 实现筛选逻辑
this.products = this.products.filter(product => {
// 根据筛选条件过滤
return true;
});
}
}
- product - list.component.html
<div class="product - list">
<input type="text" [(ngModel)]="filterText" placeholder="筛选商品">
<button (click)="filterProducts(filterText)">筛选</button>
<button (click)="sortProducts('price')">按价格排序</button>
<div *ngFor="let product of products" class="product">
<h3>{{product.name}}</h3>
<p>价格: {{product.price}}</p>
<p>库存: {{product.stock}}</p>
<p *ngIf="product.promotion">{{product.promotion}}</p>
<div [class.out - of - stock]="product.stock === 0">商品缺货</div>
</div>
</div>
- app.module.ts
import { BrowserModule } from '@angular/platform - browser';
import { NgModule } from '@angular/core';
import { HttpClientModule } from '@angular/common/http';
import { AppComponent } from './app.component';
import { ProductListComponent } from './product - list/product - list.component';
import { ProductService } from './product - service';
import { WebSocketService } from './web - socket.service';
@NgModule({
declarations: [
AppComponent,
ProductListComponent
],
imports: [
BrowserModule,
HttpClientModule
],
providers: [ProductService, WebSocketService],
bootstrap: [AppComponent]
})
export class AppModule {}