IT0018.Angular从零到一
华章IT
王芃 编著
机械工业出版社
ISBN:978-7-111-56283-2
【有道云笔记】IT0018.Angular从零到一
https://note.youdao.com/s/3y72LM3N
目录:
读书笔记:
第1章 初始Angular
时间:2023年12月07日
书里要求是node 6.x.x,npm 3.x.x
我的MAC MINI电脑上是node 20.10.0 , npm 10.2.3
到npm.taobao.org上安装cnpm命令,用npm命令install取的外国的地址,经常下载失败
安装 sudo cnpm install -g @angular/cli (和书中不一样,按angular.cn中文官网上的为准)
查看angular-cli版本:ng version (目前用的是17.1.3)
创建项目 ng new my-app
由于使用 ng new app-name 这个命令,来创建项目很慢,是由于它需要下载很多的依赖包。所以可以通过如下命令 可以解决。 在命令后面加上参数 --skip-install 如:ng new app-name --skip-install --skip-instal 意思是跳过安装 依赖包的过程。 在项目创建完成后,使用 cnpm install 来安装依赖包。
运行项目 ng serve
创建login组件 ng g c login
使用组件
// app\login\login.component.ts
import { Component } from '@angular/core';
import { CommonModule } from '@angular/common';
import { RouterOutlet } from '@angular/router';
//引入组件
import { LoginComponent } from './login/login.component';
@Component({
selector: 'app-root',
standalone: true,
imports: [CommonModule, RouterOutlet,LoginComponent], //导入
templateUrl: './app.component.html',
styleUrl: './app.component.css'
})
export class AppComponent {
title = '哈哈哈hello Angular呆呆呆';
}
//在app.component.html里用组件的标签<app-login></app-login>即可
建立一个Service完成业务逻辑: src文件夹中建立 app\core文件夹,再运行cmd命令 ng g s core\auth
//src\app\core\auth.service.ts
import { Injectable } from '@angular/core';
@Injectable({
providedIn: 'root'
})
export class AuthService {
constructor() { }
loginWithCreadentials(username:string, password:string):boolean{
console.log("传进来的",username,password);
if(username=="niunan"){
return true;
}
return false;
}
}
配置依赖注入
// src\app\app.config.ts
import { ApplicationConfig } from '@angular/core';
import { provideRouter } from '@angular/router';
import { routes } from './app.routes';
import { provideClientHydration } from '@angular/platform-browser';
import { AuthService } from './core/auth.service'; //记得要引用
export const appConfig: ApplicationConfig = {
providers: [provideRouter(routes), provideClientHydration(),
{provide:"auth",useClass:AuthService} //依赖注入
]
};
双向数据绑定及自定义验证样式
// src\app\login\login.component.ts
import { Component, Inject } from '@angular/core';
import { AuthService } from '../core/auth.service';
import { FormsModule } from '@angular/forms'; //双向绑定需要引入这个
import { CommonModule } from '@angular/common'; //*ngIf指令需要引入这个
@Component({
selector: 'app-login',
standalone: true,
imports: [FormsModule,CommonModule],
templateUrl: './login.component.html',
styleUrl: './login.component.css'
})
export class LoginComponent {
username="";
password = "";
phone="";
qq="";
constructor(@Inject("auth") private service:AuthService){ //依赖注入
}
//表单提交,感觉没用,因为始终要定义上面的username,password。。。等
onSubmit(formValue:any){
console.log("表单提交了,formValue:",formValue);
console.log(`username:${this.username},password:${this.password},phone:${this.phone},qq:${this.qq}`)
}
//单纯点击按钮
onClick(){
console.log('单纯点击按钮');
console.log(`username:${this.username},password:${this.password},phone:${this.phone},qq:${this.qq}`)
this.service.loginWithCreadentials(this.username,this.password);
var b= this.service.loginWithCreadentials(this.username,this.password);
console.log("登录结果 :",b);
}
}
<!--/ src\app\login\login.component.html-->
<form #formRef="ngForm" (ngSubmit)="onSubmit(formRef.value)">
<fieldset ngModelGroup="login">
<div>
<input name="username" type="text" required #usernameRef="ngModel" [(ngModel)]="username" placeholder="用户名" placeholder="请输入用户名" >
<div *ngIf="usernameRef.errors?.['required']">必填</div>
</div>
<div>
<input name="password" type="password" required minlength="6" #passwordRef="ngModel" [(ngModel)]="password" placeholder="请输入密码" >
<div *ngIf="passwordRef.errors?.['minlength']">密码最少6位</div>
</div>
</fieldset>
<fieldset ngModelGroup="info">
手机号<input type="text" name="phone" [(ngModel)]="phone" />
QQ:<input type="text" name="qq" [(ngModel)]="qq" />
</fieldset>
<button type="submit">登录</button>
<button type="button" (click)="onClick()">点一下后看看Control</button>
<hr />
<div>
username:{{username}},
password:{{password}}
</div>
</form>
/* src\app\login\login.component.css */
/*验证未通过文本框样式*/
input.ng-invalid{
border:1px solid red;
}
/*验证通过文本框样式*/
input.ng-valid{
border:1px solid green;
}
发布项目命令:ng build --aot
发布后IIS里建立网站目录指向 disk/browser 即可
书里的样式库:https://getmdl.io/
网站上的是CSS的,书里的封装成组件了,用的是
真的主页及各组件的使用在
之前创建的是在angular 17下的项目,所以得用命令
cnpm install @angular-mdl/core --save
来安装MDL样式库
然后在index.html引入样式文件
<link rel="stylesheet" href="https://code.getmdl.io/1.1.3/material.indigo-pink.min.css"/> <link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
以上都是可以在github上找到相关代码
然后在app.module.ts中import进来
// src\app\app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { LoginComponent } from './login/login.component';
import { routing } from './app.routes';
import { FormsModule} from '@angular/forms';
import { TodoComponent } from './todo/todo.component';
import { provideHttpClient } from '@angular/common/http';
import { MdlModule } from '@angular-mdl/core'; //加入第三方样式库
@NgModule({
declarations: [
AppComponent,
LoginComponent,
TodoComponent
],
imports: [
BrowserModule,
FormsModule,
AppRoutingModule,
routing,
MdlModule //加入第三方样式库
],
providers: [provideHttpClient()],
bootstrap: [AppComponent]
})
export class AppModule { }
在todo页面就可以直接使用了
<!-- src\app\todo\todo.component.html -->
<div style="padding:20px;">
<p>todo works!</p>
<p>
<mdl-textfield [(ngModel)]="desc" floating-label label="小目标:" type="text" (keyup.enter)="addTodo()" ></mdl-textfield>
</p>
<mdl-list>
<mdl-list-item *ngFor="let todo of todos">
<mdl-list-item-primary-content>
<mdl-checkbox (change)="toggleTodo(todo)" [(ngModel)]="todo.completed" [mdl-ripple]="true">
{{todo.id}}. {{todo.desc}}
</mdl-checkbox>
</mdl-list-item-primary-content>
<mdl-list-item-secondary-action>
<button mdl-button mdl-button-type="icon" (click)="removeTodo(todo)" mdl-colored="accent">
<mdl-icon>delete</mdl-icon>
</button>
</mdl-list-item-secondary-action>
</mdl-list-item>
</mdl-list>
<footer>
<hr />
共 {{todos.length}} 项待办
<a href="">全部</a> |
<a href="">未完成</a> |
<a href="">已完成</a>
</footer>
</div>
效果图:
自己在测试的时候碰到如下问题:
ng serve 出错:listen EACCES: permission denied ::1:4200 解决: 管理员CMD下 net stop winnat netsh int ipv4 set dynamic tcp start=49152 num=16384 netsh int ipv6 set dynamic tcp start=49152 num=16384 net start winnat 参考 https://superuser.com/questions/1437780/how-to-fix-listen-eacces-permission-denied-on-any-port