【Angular教程240104】01 目录结构分析 创建组件 声明属性的方式、ts定义属性、绑定数据、绑定属性0

Angular教程 240103

感谢大地。

快捷键


1 代码整理快捷键:

mac : ↑ + option +f
wind: shift alt f

2 windows 繁体字 繁简转换快捷键

: control+shift +f

3 侧边栏的“资源管理器”没有了,怎么也找不到,邮件也没有找到。

快捷键 Ctrl+Shift+P
或者:
选择“查看view 表示 ”下的“命令面板Command Palette コマンド パレット”
-View
- Command Palette

输入:View: Reset View Locations
ビユーの位置をリセットする

所有的视图会恢复到默认的位置

4


01 Angular介绍、安装Angular Cli、创建Angular项目 预编译器Scss Less css配置

02 Angular目录结构分析、app.module.ts详解、以及Angular中创建组件、组件详解、 绑定数据

1. Angular 目录结构分析

1根目录
  • /e2e/: 端到端的测试文件 (End-to-End) 位于这个文件夹。
  • /node_modules/: 存放所有的npm依赖包。
2/src 目录
  • /app/: 包含所有的业务逻辑和视图控制代码,是构建app的核心文件。
    • app.module.ts: 根模块文件。
  • /environments/: 包含不同环境的配置文件。
  • favicon.ico: 网站的图标。
  • index.html: 主页面。
  • main.ts: Angular的主入口文件。
  • polyfills.ts: 浏览器兼容性补丁 (polyfill) 文件。
  • styles.css: 应用的全局样式文件。
  • test.ts: 单元测试入口文件。
3根目录文件
  • .angular-cli.json: Angular CLI的配置文件。
  • .editorconfig: 编辑器配置,保持代码风格一致性。
  • .gitignore: Git的忽略配置文件。
  • karma.conf.js: Karma的单元测试配置文件。
  • package.json: 定义项目依赖和npm命令。
  • protractor.conf.js: Protractor的端到端测试配置文件。
  • README.md: 项目的README文件。
  • tsconfig.json: TypeScript编译器配置文件。
  • tslint.json: TSLint的代码质量检查配置文件。
4版本2参照

/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的这种目录结构有利于团队合作和项目的可扩展性。每个部分都有明确的职责,使得开发者可以快速定位和更新代码。这种结构也方便了测试和部署。

5app.module.ts文件
定义 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 { }

6自定义组件
创建组件

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() []     //*初始化加载的生命周期函数

}

  1. 绑定数据
    定义数据

绑定数据
Angular 中使用{{}}绑定业务逻辑里面定义的数据

03 Angular创建组件 声明属性的几种方式、ts定义属性、绑定数据、绑定属性、绑定html、数据循环、循环多维数组

1. Angular 组件、数据绑定和数据循环

1.1 创建 angualr 组件

ng g component components/news
1
使用组件:

1.2 属性–Angular数据绑定

TS文件初始化数据,html文件绑定数据

1 定义属性数据
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";


}


2 绑定属性数据
 <h3>我是一个新闻组件 </h3>
<app-header></app-header>
{{title}}
<!-- 通过花括号可以将后台定义的属性,绑定到前台 -->
<div> {{username}}
</div>
<hr>

3 声明属性的几种方式:
  public      共有  *(默认)  可以在这个类里面使用、也可以在类外面使用
  protected   保护类型        他只有在当前类和它的子类里面可以访问
  private     私有           只有在当前类才可以访问这个属性
1.3 对象–Angular数据绑定
1 定义一个对象
   public userinfo: any = {
    username: 'wdm',
    age: 33

  }
  public msg: string = '我是msg';
2 绑定对象数据

{{userinfo.username}}
{{userinfo.age}}
 


1.4 oninit angular 中 自己引入生命周期钩子
1 整个生命周期钩子地图 及OnInit的位置

import { Component, Input, OnInit, OnChanges, OnDestroy, DoCheck, AfterContentInit, AfterContentChecked, AfterViewInit, AfterViewChecked } from '@angular/core';

@Component({
  selector: 'app-example',
  template: '', 
  // 这里用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() {
    // 在组件销毁时调用
  }
}

2 import oninit如何操作

在 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() 方法中,我们可以添加初始化组件时需要执行的代码。-->
3 OnInit初始化设置的常用方法

一些常用的 ngOnInit 方法
ngOnInit 是 Angular 生命周期钩子中的一个重要方法,通常用于在组件初始化完成后执行一些初始化工作。下面是一些常用的 ngOnInit 方法示例:

1发起HTTP请求并获取数据:
 ngOnInit(): void {
  this.userService.getUserData().subscribe(data => {
    this.userData = data;
  });
}
2初始化一些组件属性:
 ngOnInit(): void {
  this.title = "Welcome to My App";
  this.subtitle = "Angular is awesome!";
}
3订阅一些服务或事件:
 ngOnInit(): void {
  this.authService.userLoggedIn.subscribe(isLoggedIn => {
    this.isUserLoggedIn = isLoggedIn;
  });
}
4执行一些其他初始化操作:
 ngOnInit(): void {
  // 执行一些其他初始化操作
  this.initializeSomething();
}
在组件
5`初始化时执行特定逻辑:
 ngOnInit(): void {
  if (this.isSpecialComponent) {
    this.specialComponentInit();
  }
}

这些示例展示了 ngOnInit 可能用于的不同情况,可以根据你的组件需求在 ngOnInit 中执行适当的初始化工作。


4 简单的完整例子

让我们通过一个简单的例子来解释这个概念。假设我们有一个组件,它显示一段欢迎消息。我们将在 ngOnInit() 方法中设置这个消息。

4-1 news.component组件

1 ts文件。

  • news.component.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);
    }


    
  }
  

  • 其中userinfo.ts

/**。首先,你定义了 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/>  


4-2显示消息在 news.component.html:

打开 news.component.html 文件,并添加以下代码来显示欢迎消息:
html

{{ welcomeMessage }}

这个例子中的 ngOnInit() 方法在组件初始化时被调用,并设置 welcomeMessage 属性。然后,这个消息在组件的 HTML 模板中通过插值表达式 {{ welcomeMessage }} 显示出来。

当你运行你的 Angular 应用并导航到这个组件时,你将看到显示了 “欢迎来到我的 Angular 应用!” 的消息。这就是 OnInit 的基本用法,它对于设置初始数据和执行启动时的逻辑非常有用。

4-3构造函数和 生命周期钩子 进行初始化 有什么区别?

constructor() {
}

ngOnInit() { } 进行初始化 有什么区别?

区别在于时机和用途:

  • constructor 在对象创建时立即调用,用于基本设置和依赖注入。
  • ngOnInit 在组件初始化阶段被调用,用于执行与组件模板和视图相关的初始化操作。
  • 在大多数情况下,应该将组件的初始化逻辑放在 ngOnInit 中,以确保在组件完全准备好时执行。如果只是进行一些基本的设置和依赖注入,可以使用 constructor。但避免在 constructor 中执行可能导致异步问题的操作,因为 Angular 在 ngOnInit 阶段提供了更安全的初始化时机。
4-4 常见初始化报错:

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 的情况。为了解决这个问题,可以采取以下几种方法之一:

  • 1给 userinfo 属性一个初始值:
  
userinfo: Userinfo = new Userinfo("", 0); // 使用默认值

这样,在构造函数中不再需要初始化 userinfo,因为它已经在属性声明时被初始化了。

  • 2 在 tsconfig.json 中启用 strictPropertyInitialization 选项(TypeScript 2.7+),这将强制要求你在构造函数中初始化类属性,或者通过属性声明时分配一个初始值。这可以提高代码的类型安全性。
  
{
  "compilerOptions": {
    "strictPropertyInitialization": true
  }
}
  • 3 如果你确定 userinfo 属性在 ngOnInit 中会被正确初始化,可以使用非空断言操作符 !:
  
userinfo!: Userinfo;

非空断言操作符 ! 的主要作用是告诉 TypeScript 编译器,在你的代码逻辑中,
你确信某个属性或变量一定会在运行时被赋值,不会为空或未定义。
如果你在代码中省略了 !,那么 TypeScript 将进行严格的空值检查,
如果存在潜在的空值情况,会发出编译时的警告或错误。

并要求你在使用变量或属性之前进行空值检查或确保其值不为空。
这是 TypeScript 的一种类型安全机制,旨在防止潜在的空值错误,提高代码的健壮性。
因此,与userinfo: Userinfo;相比,userinfo!: Userinfo;
这将告诉 TypeScript 编译器,虽然没有在构造函数中初始化 userinfo,但在 ngOnInit 中会被正确初始化,因此可以放心地使用它。不过要确保在 ngOnInit 中确实对 userinfo 进行了初始化,以避免运行时错误。

选择哪种方法取决于的需求和设计,但在实际开发中,最好在构造函数中或属性声明时进行属性的初始化,以确保代码的可维护性和类型安全性。

1.5 绑定属性

1.html


angular绑定属性:

鼠标瞄上来看一下
1.6 angular还支持简单的计算

angular还支持简单的计算

1+2={{1+2}}

运行结果:

1.7 数据循环 *ngFor

1.4.1 示例01:

这两种定义数组的方式都是相当nice的。

// public arrs: string[] = [‘一’, ‘二’, ‘三’, ‘四’, ‘五’]; // 推荐写法
public arrs: Array = [‘一’, ‘二’, ‘三’, ‘四’, ‘五’];
1
2



  • {{arr}}

1.4.2 示例02:

public userlist:any[]=[{
username:‘张三’,
age:20
},{
username:‘李四’,
age:21
},
{
username:‘王五’,
age:40
}];

  • {{item.username}}-------{{item.age}}

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万’,
},
],
},
];

  • {{item.cate}}
    1. {{car.title}}-----{{car.price}}

1.4.4 循环数据:显示索引

public list: any[] = [
{ title: ‘我是新闻01’ },
{ title: ‘我是新闻02’ },
{ title: ‘我是新闻03’ },
{ title: ‘我是新闻04’ },
{ title: ‘我是新闻05’ },
];

循环数据,显示数据的索引值(key)

    你可能感兴趣的:(angular.js,前端,javascript)