angular笔记2

前端之家收集整理的这篇文章主要介绍了angular笔记2前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

angular架构概览

我们是这样写 Angular 应用的:用 Angular扩展语法编写 HTML 模板, 用组件类管理这些模板,用服务添加应用逻辑, 用模块打包发布组件与服务。

然后,我们通过引导根模块来启动该应用。 Angular在浏览器中接管、展现应用的内容,并根据我们提供的操作指令响应用户的交互。

这个架构图展现了Angular应用中的 8 个主要构造块:

  • 模块 (module)
  • 组件 (component)
  • 模板 (template)
  • 元数据 (Metadata)
  • 数据绑定 (data binding)
  • 指令 (directive)
  • 服务 (service)
  • 依赖注入 (dependency injection)

模块 (module)

Angular 应用是模块化的,并且Angular有自己的模块系统,它被称为 Angular模块或NgModules
每个 Angular 应用至少有一个模块(根模块),习惯上命名为AppModule
Angular 模块(无论是根模块还是特性模块)都是一个带有@NgModule装饰器的类。

装饰器是用来修饰 JavaScript 类的函数。 Angular 有很多装饰器,它们负责把元数据附加到类上,以了解那些类的设计意图以及它们应如何工作。

NgModule是一个装饰器函数,它接收一个用来描述模块属性的元数据对象。其中最重要的属性
- declarations - 声明本模块中拥有的视图类。Angular 有三种视图类:components,directives,和 pipes.
- exports - declarations 的子集,可用于其它模块的组件模板。
- imports - 本模块声明的组件模板需要的components,directives所在的其它模块。
- providers - 服务的创建者,并加入到全局服务列表中,可用于应用任何部分。
- bootstrap - 指定应用的主视图root component,通过它管理其它视图。只有root module才能设置bootstrap属性

src/app/app.module.ts

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
@NgModule({
  imports:      [ BrowserModule ],providers:    [ Logger ],declarations: [ AppComponent ],exports:      [ AppComponent ],bootstrap:    [ AppComponent ]
})
export class AppModule { }

AppComponent的export语句只是用于演示如何导出的,它在这个例子中并不是必须的。根模块不需要导出任何东西,因为其它组件不需要导入根模块。

我们通过引导根模块来启动应用。 在开发期间,你通常在一个main.ts文件中引导AppModule,就像这样:

src/main.ts

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';

platformBrowserDynamic().bootstrapModule(AppModule);

Angular 模块 vs. JavaScript 模块

Angular 模块(一个用@NgModule装饰的类)是 Angular 的基础特性。

JavaScript 也有自己的模块系统,用来管理一组 JavaScript 对象。 它与 Angular 的模块系统完全不同且完全无关。
JavaScript 中,每个文件是一个模块,文件中定义的所有对象都从属于那个模块。 通过export关键字,模块可以把它的某些对象声明为公共的。 其它 JavaScript 模块可以使用import 语句来访问这些公共对象。

import { NgModule }     from '@angular/core';
import { AppComponent } from './app.component';
export class AppModule { }

Angular libraries

每个 Angular 库的名字都带有@angular前缀。

JavaScriptimport语句导入其中某些部件。

@angular/core库中导入Component装饰器

import { Component } from '@angular/core';

还可以使用 JavaScript 的导入语句从 Angular 库中导入 Angular 模块。

import { BrowserModule } from '@angular/platform-browser';

在上面那个简单的根模块的例子中,应用模块需要BrowserModule的某些素材。要访问这些素材,就得把它加入@NgModule元数据的imports

imports:  [ BrowserModule ],

这种情况下,你同时使用了 AngularJavaScript 的模块化系统。

Templates

bootstrap编写的简单模板
编辑src/app/app.my-navbar.css

.bs-docs-nav .navbar-toggle .icon-bar {
  background-color: #563d7c;
}
.bs-docs-nav .navbar-brand,.bs-docs-nav .navbar-nav > li > a {
  font-weight: 500;
  color: #563d7c;
}

编辑src/app/app.my-navbar.html

<header class="navbar navbar-static-top bs-docs-nav"> <div class="containter"> <div class="navbar-header"> <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-navbar" aria-expanded="false"> <span class="sr-only">Toggle navigation</span> <span class="icon-bar"></span> <span class="icon-bar"></span> <span class="icon-bar"></span> </button> <a href="../" class="navbar-brand">Angular</a> </div> <nav class="collapse navbar-collapse" id="bs-navbar"> <ul class="nav navbar-nav"> <li *ngFor="let navLink of navLinks"> <a [href]="navLink.href">@H_301_525@{{navLink.name}}</a> </li> </ul> <form class="navbar-form navbar-left"> <div class="form-group"> <input type="text" class="form-control" (keyup)="changeTitle($event)" placeholder="Search"> </div> <div class="form-group"> <input type="text" class="form-control" [(ngModel)]="title" name="title" placeholder="Search"> </div> <button type="submit" class="btn btn-default">Submit</button> </form> <ul class="nav navbar-nav navbar-right"> <li> <a href="./">@H_301_525@{{ title }}</a> </li> </ul> </nav> </div> </header>

Metadata


元数据告诉 Angular 如何处理一个类.
AppNavBarComponent真的只是一个类。直到我们告诉 Angular 它是一个组件。

要告诉 Angular AppNavBarComponent是个组件,只要把元数据附加到这个类。
TypeScript中,我们用装饰器 (decorator) 来附加元数据。

import { Component } from '@angular/core';

@Component({
  selector: 'app-navbar',templateUrl: './app.my-navbar.html',styleUrls: ['./app.my-navbar.css']
})

export class AppNavBarComponent {
  title = 'Angular Demo';
  navLinks = [{href:"#",name:"FEATURES"},{href:"#",name:"DOCS"}];
  changeTitle = function(event:any){
    this.title = event.target.value;
  }
}

selector: CSS 选择器,它告诉 Angular 在父级 HTML 中查找<app-navbar>标签,创建并插入该组件。 例如,如果应用的 HTML 包含<app-navbar></app-navbar>Angular 就会把AppNavBarComponent的一个实例插入到这个标签中。

Data binding

<li *ngFor="let navLink of navLinks"> <a [href]="navLink.href">@H_301_525@{{navLink.name}}</a> </li>

单向绑定

{{navLink.name}}插值表达式在<a>标签显示组件的name属性的值。
[href]绑定数据到属性里面,数据从componentview
(keyup)="changeTitle($event)"绑定keyup输入事件,数据从viewcomponent

双向绑定

在双向绑定中,数据属性值通过属性绑定从组件流到输入框。用户修改通过事件绑定流回组件,把属性值设置为最新的值。

<input type="text" class="form-control" [(ngModel)]="title" name="title" placeholder="Search">

Directives


Angular 模板是动态的。当 Angular 渲染它们时,它会根据指令提供的操作对 DOM 进行转换。
组件是一个带模板的指令;@Component装饰器实际上就是一个@Directive装饰器,只是扩展了一些面向模板的特性。

还有两种其它类型的指令:结构型(Structural)指令和属性(attribute)型指令。

结构型(Structural)指令

结构型(Structural)指令通过在 DOM添加、移除和替换元素来修改布局。

<li *ngFor="let navLink of navLinks"> <a [href]="navLink.href">@H_301_525@{{navLink.name}}</a> </li>

*ngFor告诉 Angular遍历navLinks生成<li>标签

属性(attribute)型指令

<input type="text" class="form-control" [(ngModel)]="title" name="title" placeholder="Search">

ngModel指令就是属性型指令的一个例子,它实现了双向数据绑定。ngModel修改现有元素(一般是)的行为:设置其显示属性值,并响应 change 事件。

Services


几乎任何东西都可以是一个服务。 典型的服务是一个类,具有专注的、明确的用途。它应该做一件特定的事情,并把它做好。
例如:
- 日志服务
- 数据服务
- 消息服务

下面是一个服务类的范例,用于把日志记录到浏览器的控制台:
编辑src/app/service/logger.service.ts

import {Injectable} from '@angular/core';
@Injectable()
export class Logger {
  log(msg:any) {
      console.log('From logger class: ' + msg);
  }
}

编辑src/app/app.module.ts

import { Logger } from './logger.service';
@NgModule({
  ...
  providers: [Logger],...
})

Dependency injection

Dependency injection is a way to supply a new instance of a class with the fully-formed dependencies it requires. Most dependencies are services. Angular uses dependency injection to provide new components with the services they need.

Angular can tell which services a component needs by looking at the types of its constructor parameters. For example,the constructor of your HeroListComponent needs a HeroService:

When Angular creates a component,it first asks an injector for the services that the component requires.

An injector maintains a container of service instances that it has prevIoUsly created. If a requested service instance is not in the container,the injector makes one and adds it to the container before returning the service to Angular. When all requested services have been resolved and returned,Angular can call the component's constructor with those services as arguments. This is dependency injection.

用依赖注入模拟数据

编辑src/app/model/User.ts

export class User{
    constructor(
        private name:string,private age:number,private email:string
    ){}
}

编辑src/app/mock/user-data.mock.ts

import {User} from '../model/User';

export const Users:User[] = [
    new User("angular1",21,"2290910211@qq.com"),new User("angular2",22,new User("angular3",23,new User("angular4",24,new User("angular5",25,new User("angular6",26,]

创建一个获取用户数据的服务

编辑app/services/user.service.ts

import {Injectable} from '@angular/core';
import {Users} from '../mock/user-data.mock';
import {Logger} from "./logger.service";

@Injectable()
export class UserService{
    constructor(private Log:Logger){

    }
    getUsers(){
        this.Log.log("Get User!");
        return Users;
    }
}

@Injectable()标志着一个类可以被一个注入器实例化
我们要在@Component的元数据中使用providers声明我们所需要的依赖,还要引入User类来帮助我们声明数据的类型.

import { Component } from '@angular/core';
import { Logger } from './service/logger.service';
import { User } from './model/User';
import { UserService } from './service/user.service';

@Component({
  selector: 'app-navbar',styleUrls: ['./app.my-navbar.css'],providers:[
    Logger,UserService
  ]
})

export class AppNavBarComponent {
  title:'Angular Demo';
  users: User[];

  constructor(
    private Log:Logger,private userService:UserService
  ){
    this.users = userService.getUsers();
  }
  navLinks = [{href:"#",name:"DOCS"}];
  changeTitle = function(event:any){
    this.title = event.target.value;
  }
}

如果这个时候你试图把user.service.ts@Injectable注释掉的话,整个程序是没有报错的,但是我们建议为每个服务类都添加@Injectable(),包括那些没有依赖所以技术上不需要它的.因为:(1)面向未来,没有必要记得在后来添加了一个依赖的时候添加@Injectable().(2)一致性,所有的服务都遵循同样的规则,并且我们不需要考虑为什么少一个装饰器.

引入bootstrap样式

npm install jquery bootstrap --save

安装类型描述文件

npm install @types/jquery --save-dev

修改angular-cli.json

"apps": [
  {
    "root": "src","outDir": "dist","assets": [
      "assets","favicon.ico"
    ],"index": "index.html","main": "main.ts","test": "test.ts","tsconfig": "tsconfig.app.json","testTsconfig": "tsconfig.spec.json","prefix": "app","styles": [
        "styles.css","../node_modules/bootstrap/dist/css/bootstrap.min.css","../node_modules/bootstrap/dist/css/bootstrap-theme.min.css"
      ],"scripts": [
        "../node_modules/jquery/dist/jquery.js","../node_modules/bootstrap/dist/js/bootstrap.min.js"
      ],}
]

修改tsconfig.app.jsonjquery添加types

{
  "extends": "../tsconfig.json","compilerOptions": { "outDir": "../out-tsc/app","module": "es2015","baseUrl": "","types": ["jquery"] },"exclude": [ "test.ts","**/*.spec.ts" ] }

如果样式没有加载,删除node_modules文件夹重新npm install,不要用cnpm install

参考

猜你在找的Angularjs相关文章