项目简介
Angular 是现代的、开源的 Web 应用框架,提供组件、表单、路由和服务端渲染等完整工具集,用于构建移动端和桌面端的 Web 应用。
README 预览
Angular - The modern web developer's platform\n\n\n \n \n Angular is a development platform for building mobile and desktop web applications\n using TypeScript/JavaScript and other languages.\n \n\n\n\n angular.dev\n \n\n\n\n Contributing Guidelines\n ·\n Submit an Issue\n ·\n Blog\n \n \n\n\n\n \n \n \n\n\n\n\n## Documentation\n\nGet started with Angular, learn the fundamentals and explore advanced topics on our documentation website.\n\n- [Getting Started][quickstart]\n- [Architecture][architecture]\n- [Components and Templates][componentstemplates]\n- [Forms][forms]\n- [API][api]\n\n### Advanced\n\n- [Angular Elements][angularelements]\n- [Server Side Rendering][ssr]\n- [Schematics][schematics]\n- [Lazy Loading][lazyloading]\n- [Animations][animations]\n\n### Local Development\n\nTo contribute to the Angular Docs, check out the [Angular.dev README](adev/README.md)\n\n## Development Setup\n\n### Prerequisites\n\n- Install [Node.js] which includes [Node Package Manager][npm]\n\n### Setting Up a Project\n\nInstall the Angular CLI globally:\n\n```\nnpm install -g @angular/cli\n```\n\nCreate a workspace:\n\n```\nng new [PROJECT NAME]\n```\n\nRun the application:\n\n```\ncd [PROJECT NAME]\nng serve\n```\n\nAngular is cross-platform, fast, scalable, has incredible tooling, and is loved by millions.\n\n## Quickstart\n\n[Get started in 5 minutes][quickstart].\n\n## Ecosystem\n\n\n \n\n\n- [Angular Command Line (CLI)][cli]\n- [Angular Material][angularmaterial]\n\n## Changelog\n\n[Learn about the latest improvements][changelog].\n\n## Upgrading\n\nCheck out our [upgrade guide](https://angular.dev/update-guide/) to find out the best way to upgrade your project.\n\n## Contributing\n\n### Contributing Guidelines\n\nRead through our [contributing guidelines][contributing] to learn about our submission process, coding rules, and more.\n\n### Want to Help?\n\nWant to report a bug, contribute some code, or improve the documentation? Excellent! Read up on ou
常见问题 (5)
故障排除为什么 Angular @if、@for 或 @switch 块中的 SVG 会进入默认的 ng-content 插槽,而不是匹配 select="svg"?
这是一个 Angular 编译器缺陷,影响作为控制流块根节点的 SVG 或 MathML 元素。Angular 会生成带命名空间的标签(如 :svg:svg),因此无法匹配 ng-content 的标签选择器(如 select="svg"),该元素会被投影到默认插槽中。
变通方法:在根 SVG 或 MathML 元素上添加 ngProjectAs:
@if (saving()) {
<svg class="spinner" ngProjectAs="svg">...</svg>
} @else {
<svg ngProjectAs="svg">...</svg>
}
对于 MathML,使用:
<math ngProjectAs="math">...</math>
同样的变通方法也适用于 @for、@switch 和 *ngIf 的根节点。属性选择器和类选择器不受影响。Angular 编译器 PR 中已提供永久修复;一旦包含该修复的版本发布,请升级 Angular。
故障排除为什么升级到 Angular 22 后,Angular 库组件在 Storybook、Jest、Vitest 或 TestBed 中停止重新渲染(视图空白/过期)?
原因:Angular 22 的 JIT 路径(ɵɵngDeclareComponent → convertDeclareComponentFacadeToMetadata)会忽略声明的库版本,并将 changeDetection 默认设为 OnPush;而 AOT linker 则正确地将使用 Angular < 22 编译的组件保持为 Default/Eager。在 v22 之前以 partial 模式编译的库(例如使用 Angular 20.3 编译的 Kendo UI for Angular)可能会在订阅内部给状态赋值而不调用 markForCheck(),因此在基于 JIT 的工具(Storybook、jest-preset-angular、Vitest、TestBed、ng serve --aot=false)中视图永远不会刷新,而 AOT 构建则工作正常。临时解决方案:在任何库声明被求值之前为 JIT 编译器 facade 打补丁(例如,在 Storybook preview 配置或测试设置文件中):
import '@angular/compiler';
import { ChangeDetectionStrategy } from '@angular/core';
const facade = (globalThis as any).ng?.ɵcompilerFacade;
const original = facade.compileComponentDeclaration.bind(facade);
facade.compileComponentDeclaration = (env: unknown, url: string, decl: any) => {
const major = Number.parseInt(String(decl.version ?? '0').split('.')[0], 10);
const patched =
decl.changeDetection == null && major > 0 && major < 22
? { ...decl, changeDetection: ChangeDetectionStrategy.Eager }
: decl;
return original(env, url, patched);
};
或者,在库的组件中显式设置 changeDetection: ChangeDetectionStrategy.Default,并使用 Angular 22 重新发布。修复进展可在 angular/angular#71107 跟踪。
故障排除为什么在使用 withI18nSupport() 时,ICU 复数文本在 Angular SSR 水合(hydration)后会出现重复?
这是一个已知的 Angular bug(issue #71425),影响 provideClientHydration(withI18nSupport())。当同一个包含 ICU 表达式(例如 {count, plural, ...})的组件在页面中出现多次时,服务器会对 hydration 数据进行去重,导致两个实例共享同一个 ngh 对象。随后客户端会通过 shift() 修改这个共享的 ICU case 队列,因此只有第一个实例能够正确 hydrate——后续实例会将 ICU 内容渲染两次(生产环境),或者抛出 ASSERTION ERROR: expected matching nodeType [Expected=> 8 == 3 <=Actual](开发模式)。
**变通方案:** 用控制流和独立的 i18n 消息替换 ICU 表达式:
@if (count === 1) {
<ng-container i18n>1 item</ng-container>
} @else {
<ng-container i18n>{{ count }} items</ng-container>
}
这样可以完全避开共享的 ICU case 队列。该 bug 存在于 Angular 18.2 到至少 21.2/22.x 版本中,因此升级版本并无帮助——在修复发布之前请使用该变通方案(提议的修复方式是使用 [...caseQueue] 复制 case 队列,而不是修改共享的序列化数据)。
故障排除如何在绑定 iframe src 时修复 Angular NG0904 "Unsafe value used in a resource URL context" 错误?
当普通字符串被绑定到资源 URL 属性(如 <iframe [src]>)时,会发生 NG0904。对于资源 URL 而言,调用 sanitize(SecurityContext.URL, url) 是不够的;Angular 要求使用显式信任的 SafeResourceUrl。
使用 bypassSecurityTrustResourceUrl 修复:
import { Component, inject } from '@angular/core';
import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser';
@Component({
selector: 'app-root',
template: `<iframe [src]="trustedUrl"></iframe>`,
})
export class App {
readonly url = 'data:image/svg+xml;base64,...';
private readonly sanitizer = inject(DomSanitizer);
readonly trustedUrl: SafeResourceUrl =
this.sanitizer.bypassSecurityTrustResourceUrl(this.url);
}
仅对你信任的 URL 使用此方法,尤其是 data: URL 或用户提供的 URL。对于不受信任的输入,请根据允许列表进行验证,或者不要将其绑定到资源 URL。
故障排除如何修复 Angular DevTools 在嵌套路由中将 home 根路由显示为激活状态的问题?
这是一个已知的 Angular DevTools 路由高亮显示 bug:当查看诸如 /posts/1 的嵌套 URL 时,根路由 / 会被错误地标记为激活状态,尽管它并非当前激活的路由。该问题已在 angular/angular#65037 中修复。
解决方法:
1. 更新 Angular DevTools 浏览器扩展。
- Chrome/Edge:打开 chrome://extensions,启用开发者模式,点击**更新**,然后重新打开 DevTools。
- Firefox:在 about:addons 中更新 Angular DevTools。
2. 如果在本地运行 DevTools,请拉取最新代码并重新构建:
git pull origin main
npm install
npm start或者,cherry-pick 或合并 PR #65037。
无需对应用程序的路由进行任何更改。在更新之前,请将 / 上显示的激活徽标视为纯显示层面的 bug,并使用 Router.url 或路由事件来验证当前路由。