感谢大地。
mac : ↑ + option +f
wind: shift alt f
: control+shift +f
快捷键 Ctrl+Shift+P
或者:
选择“查看view 表示 ”下的“命令面板Command Palette コマンド パレット”
-View
- Command Palette
输入:View: Reset View Locations
ビユーの位置をリセットする
所有的视图会恢复到默认的位置
/src 目录: 这是项目的主要目录,包含应用程序的所有源代码。
app 文件夹: 包含应用程序的核心文件,如模块、组件、服务和管道。
components: 存放自定义组件。
services: 存放服务文件,用于业务逻辑和数据管理。
models: 定义数据模型。
assets: 存放静态资源,如图片、样式表和JSON文件。
environments: 包含不同环境的配置文件,如开发和生产环境。
/node_modules 目录: 存放所有的npm依赖包。
/e2e 目录: 存放端到端测试文件。
根目录文件:
angular.json: Angular CLI的配置文件。
package.json 和 package-lock.json: 定义项目依赖和锁定版本。
tsconfig.json: TypeScript编译器的配置文件。
/dist 目录: 存放构建后的文件,用于部署。
Angular的这种目录结构有利于团队合作和项目的可扩展性。每个部分都有明确的职责,使得开发者可以快速定位和更新代码。这种结构也方便了测试和部署。
定义 AppModule,这个根模块会告诉 Angular 如何组装该应用。
/*这个文件是Angular 根模块,告诉Angular如何组装应用*/
//BrowserModule,浏览器解析的模块
import { BrowserModule } from '@angular/platform-browser';
//Angular核心模块
import { NgModule } from '@angular/core';
//根组件
import { AppComponent } from './app.component';
//使用命令 ng g component components/news 也是自动引入 并声明配置在 declarations 项目运行所需要的组建中去
import { NewsComponent } from './components/news/news.component';
import { HomeComponent } from './components/home/home.component';
import { HeaderComponent } from './components/header/header.component';
/*@NgModule装饰器, @NgModule接受一个元数据对象,告诉 Angular 如何编译和启动应用*/
@NgModule({
declarations: [ /*配置当前项目运行的的组件*/
AppComponent,
NewsComponent,
HomeComponent,
HeaderComponent
],
imports: [ /*配置当前模块运行依赖的其他模块*/
BrowserModule
],
providers: [], /*配置项目所需要的服务*/
bootstrap: [AppComponent] /* 指定应用的主视图(称为根组件) 通过引导根AppModule来启动应用 ,这里一般写的是根组件*/
})
//表示暴露根模块 ,但根模块不需要导出任何东西, 因为其它组件不需要导入根模块
export class AppModule { }
ng g component components/header
ng g component components/news
import { Component,OnInit }from '@angular/core';
//*引入 angular 核心
@Component({
selector:'app-header', //*使用这个组件的名称
templateUrl:'./header.component.html',//*html 模板
styleUrls: ['./header.component.css'] //*css 样式
})
//export暴露整个组件
export class HeaderComponent implements OnInit {//*实现接口
title='my-app'; //定义属性
constructor(){//*构造函数
}
ngOnInt() [] //*初始化加载的生命周期函数
}
绑定数据
Angular 中使用{{}}绑定业务逻辑里面定义的数据
ng g component components/news
1
使用组件:
TS文件初始化数据,html文件绑定数据
import { Component } from '@angular/core';
@Component({
selector: 'app-news',
templateUrl: './news.component.html',
styleUrls: ['./news.component.scss']
})
export class NewsComponent {
title = "--ts 我是一个新闻组件的属性";//后台定义的属性,要绑定到前台来使用
// public title = "我是一个新闻组件的属性"; 完整版 是要声明属性的公开程度
public username: string = "zyy";
}
<h3>我是一个新闻组件 </h3>
<app-header></app-header>
{{title}}
<!-- 通过花括号可以将后台定义的属性,绑定到前台 -->
<div> {{username}}
</div>
<hr>
public 共有 *(默认) 可以在这个类里面使用、也可以在类外面使用
protected 保护类型 他只有在当前类和它的子类里面可以访问
private 私有 只有在当前类才可以访问这个属性
public userinfo: any = {
username: 'wdm',
age: 33
}
public msg: string = '我是msg';
{{userinfo.username}}
{{userinfo.age}}
import { Component, Input, OnInit, OnChanges, OnDestroy, DoCheck, AfterContentInit, AfterContentChecked, AfterViewInit, AfterViewChecked } from '@angular/core';
@Component({
selector: 'app-example',
template: '<ng-content></ng-content>',
// 这里用ng-content投射内容
})
export class ExampleComponent implements OnInit, OnChanges, OnDestroy, DoCheck, AfterContentInit, AfterContentChecked, AfterViewInit, AfterViewChecked {
@Input() data: any; // 绑定的属性
constructor() { }
ngOnChanges() {
// 当@Input绑定的属性发生变动时调用
}
ngOnInit() {
// 在组件初始化时调用
}
ngDoCheck() {
// 在每次变更检测运行期间调用
}
ngAfterContentInit() {
// 在内容(或ng-content)投射到视图时调用
}
ngAfterContentChecked() {
// 每次投射的内容发生改变时调用
}
ngAfterViewInit() {
// 在组件(和子组件)初始化完成时调用
}
ngAfterViewChecked() {
// 每次组件(和子组件)视图被检测时调用
}
ngOnDestroy() {
// 在组件销毁时调用
}
}
在 Angular 中,当你使用 Angular CLI 来生成一个新的组件时,默认情况下 OnInit 生命周期钩子并不会自动被引入或实现。你需要手动添加这些部分。
OnInit 是一个 Angular 生命周期钩子,用于在组件初始化时执行代码。这意味着当你的组件准备好显示或与之交互时,Angular 会调用 ngOnInit() 方法。
在 Angular 中,如果你想在你的组件中使用 OnInit 生命周期钩子,你需要遵循以下步骤:
1 引入 OnInit:
首先,你需要从 @angular/core 包中引入 OnInit。这是通过使用 import 语句完成的。
2 实现 OnInit 接口:
在你的组件类中实现 OnInit 接口。这意味着你的[组件类]将包含一个特定的方法 ngOnInit(),Angular 会在初始化组件时调用这个方法。
3 定义 ngOnInit() 方法:
在你的组件类中定义 ngOnInit() 方法。在这个方法内部,你可以放置初始化组件所需的逻辑。
以下是一个简单的例子:
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-my-component',
templateUrl: './my-component.component.html',
styleUrls: ['./my-component.component.css']
})
export class MyComponent implements OnInit {
constructor() { }
ngOnInit(): void {
// 在这里编写初始化逻辑
}
}
<!--我们从 @angular/core 导入了 Component 和 OnInit。
我们创建了一个名为 MyComponent 的新组件。
我们通过实现 OnInit 接口表明这个组件将使用 OnInit 生命周期钩子。
在 ngOnInit() 方法中,我们可以添加初始化组件时需要执行的代码。-->
一些常用的 ngOnInit 方法
ngOnInit 是 Angular 生命周期钩子中的一个重要方法,通常用于在组件初始化完成后执行一些初始化工作。下面是一些常用的 ngOnInit 方法示例:
ngOnInit(): void {
this.userService.getUserData().subscribe(data => {
this.userData = data;
});
}
ngOnInit(): void {
this.title = "Welcome to My App";
this.subtitle = "Angular is awesome!";
}
ngOnInit(): void {
this.authService.userLoggedIn.subscribe(isLoggedIn => {
this.isUserLoggedIn = isLoggedIn;
});
}
ngOnInit(): void {
// 执行一些其他初始化操作
this.initializeSomething();
}
在组件
ngOnInit(): void {
if (this.isSpecialComponent) {
this.specialComponentInit();
}
}
这些示例展示了 ngOnInit 可能用于的不同情况,可以根据你的组件需求在 ngOnInit 中执行适当的初始化工作。
让我们通过一个简单的例子来解释这个概念。假设我们有一个组件,它显示一段欢迎消息。我们将在 ngOnInit() 方法中设置这个消息。
1 ts文件。
import { Component } from '@angular/core';
import { OnInit } from '@angular/core';
import { Userinfo } from './userinfo';
@Component({
selector: 'app-news',
templateUrl: './news.component.html',
styleUrls: ['./news.component.scss']
})
export class NewsComponent implements OnInit {
// 第一种:直接在构造函数中 进行生命周期设置的初始化赋值
//第二种 :在ngOnInit中进行 初始化设置
constructor() { }
welcomeMessage!: String;//定义一个属性
userinfo: Userinfo = new Userinfo("", 0); // 使用默认值
// 或着: userinfo!: Userinfo; //
ngOnInit(): void {
// 在 ngOnInit 中执行初始化逻辑
// 1 初始化 属性 赋值
this.welcomeMessage = '欢迎来到俺的 Angular 应用!';
console.log(this.welcomeMessage);
alert(this.welcomeMessage);
//--------------
//2 初始化 特定的逻辑
this.userinfo = new Userinfo("Alice", 30);
}
}
/**。首先,你定义了 class Userinfo 在 NewsComponent 内部,但 TypeScript 不允许在类内部直接定义其他类。需要将 Userinfo 类移出 NewsComponent 类。
另外,为了能够正确地在 NewsComponent 中使用 Userinfo 类,需要确保 Userinfo 类的定义位于 NewsComponent 类之前,或者将它提取到一个单独的 TypeScript 文件中,并在需要的地方引入它。
以下是修复后的代码:
首先,将 Userinfo 类定义提取到一个单独的 TypeScript 文件,例如 userinfo.ts。
在 NewsComponent 中引入 Userinfo 类,并使用它。
*/
export class Userinfo {
// 在这里定义构造函数、属性、方法等
constructor(name: string, age: number) {
this.name = name;
this.age = age;
}
// 还可以定义其他属性和方法
name: string;
age: number;
getInfo() {
return `Name: ${this.name}, Age: ${this.age}`;
}
}
2 html文件
<h3>我是一个新闻组件 </h3>
<app-header></app-header>
<h3> </h3>
{{welcomeMessage}}
<br/>
{{userinfo.name}}
{{userinfo.age}}
<br/>
打开 news.component.html 文件,并添加以下代码来显示欢迎消息:
html
当你运行你的 Angular 应用并导航到这个组件时,你将看到显示了 “欢迎来到我的 Angular 应用!” 的消息。这就是 OnInit 的基本用法,它对于设置初始数据和执行启动时的逻辑非常有用。
constructor() {
}
ngOnInit() { } 进行初始化 有什么区别?
区别在于时机和用途:
Property ‘userinfo’ has no initializer and is not definitely assigned in the constructor.ts(2564)
(property) NewsComponent.userinfo: Userinfo
属性’userinfo’没有初始化器,并且在构造函数中没有被确定赋值.ts(2564)
(property) NewsComponent.userinfo: 用户信息
这个错误是 TypeScript 中的一个编译器警告,它表示 userinfo 属性没有在构造函数中初始化并且没有被标记为可以为 null 或 undefined 的情况。为了解决这个问题,可以采取以下几种方法之一:
userinfo: Userinfo = new Userinfo("", 0); // 使用默认值
这样,在构造函数中不再需要初始化 userinfo,因为它已经在属性声明时被初始化了。
{
"compilerOptions": {
"strictPropertyInitialization": true
}
}
userinfo!: Userinfo;
非空断言操作符 ! 的主要作用是告诉 TypeScript 编译器,在你的代码逻辑中,
你确信某个属性或变量一定会在运行时被赋值,不会为空或未定义。
如果你在代码中省略了 !,那么 TypeScript 将进行严格的空值检查,
如果存在潜在的空值情况,会发出编译时的警告或错误。
并要求你在使用变量或属性之前进行空值检查或确保其值不为空。
这是 TypeScript 的一种类型安全机制,旨在防止潜在的空值错误,提高代码的健壮性。
因此,与userinfo: Userinfo;相比,userinfo!: Userinfo;
这将告诉 TypeScript 编译器,虽然没有在构造函数中初始化 userinfo,但在 ngOnInit 中会被正确初始化,因此可以放心地使用它。不过要确保在 ngOnInit 中确实对 userinfo 进行了初始化,以避免运行时错误。
选择哪种方法取决于的需求和设计,但在实际开发中,最好在构造函数中或属性声明时进行属性的初始化,以确保代码的可维护性和类型安全性。
1.html
<br/>
<h3>angular绑定属性:
</h3>
<div title="我是div angular绑定属性">鼠标瞄上来看一下 </div>
<h1>angular还支持简单的计算</h1>
<h2>1+2={{1+2}}</h2>
运行结果:
1.4.1 示例01:
这两种定义数组的方式都是相当nice的。
// public arrs: string[] = [‘一’, ‘二’, ‘三’, ‘四’, ‘五’]; // 推荐写法
public arrs: Array = [‘一’, ‘二’, ‘三’, ‘四’, ‘五’];
1
2
1.4.2 示例02:
public userlist:any[]=[{
username:‘张三’,
age:20
},{
username:‘李四’,
age:21
},
{
username:‘王五’,
age:40
}];
<ul>
<li *ngFor="let item of userlist">
{{item.username}}-------{{item.age}}
</li>
</ul>
1.4.3 示例03:
public cars: any[] = [
{
cate: ‘宝马’,
list: [
{
title: ‘宝马x1’,
price: ‘30万’,
},
{
title: ‘宝马x2’,
price: ‘30万’,
},
{
title: ‘宝马x3’,
price: ‘40万’,
},
],
},
{
cate: ‘奥迪’,
list: [
{
title: ‘奥迪q1’,
price: ‘40万’,
},
{
title: ‘奥迪q2’,
price: ‘40万’,
},
{
title: ‘奥迪q3’,
price: ‘30万’,
},
],
},
];
<ul>
<li *ngFor="let item of cars">
<b>{{item.cate}}</b>
<ol>
<li *ngFor="let car of item.list">
<i>{{car.title}}</i>-----<i>{{car.price}}</i>
</li>
</ol>
</li>
</ul>
1.4.4 循环数据:显示索引
public list: any[] = [
{ title: ‘我是新闻01’ },
{ title: ‘我是新闻02’ },
{ title: ‘我是新闻03’ },
{ title: ‘我是新闻04’ },
{ title: ‘我是新闻05’ },
];