潘任龙
    • Create new note
    • Create a note from template
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Write
        • Only me
        • Signed-in users
        • Everyone
        Only me Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Save as template
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
Create Create new note Create a note from template
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Write
Only me
  • Only me
  • Signed-in users
  • Everyone
Only me Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    Angular Note ============ [TOC] Basic Structure === ![](https://www.tutorialandexample.com/wp-content/uploads/2019/07/Various-units-are-combined-to-build-an-angular-application.jpg) Component === ## Basis selector: 以自定义元素形式展现在view 层 template: 可以是文件路径(templateUrl)也可以是内容(template) style: 外联属性为``styleUrl``, 外联属性会覆盖内联属性中的相同样式 父子组件可通过数据绑定来交互,template作为连接桥梁 `Input`: 属性绑定. `Output`: 事件绑定. 输入输出可以使用属性annotation修饰, 也可以使用组件元数据. eg: ``` @Component({ inputs:['propertyA'], outputs:['propertyB'] }) export class DemoComponent { propertyA:any={}; propertyB = new EventEmitter<number>(); } ``` customize component bidirectional data binding https://www.jianshu.com/p/752844cd6651 Angular 的组件概念基于W3C的 WebComponent ### W3C WebComponent 1. Customize Element 1. Template 1. Shadow DOM 1. HTML import ### 引用 #### Import view class 若要在组件的模板中使用其他组件element, 需要在当前组件所属的模块中声明(declarations)需要的其他组件 #### Export view class 若要在其他模块中使用当前组件,需要将组件在当前模块中导出(exports), 然后在其他模块中导入(imports)当前模块 ### Inject service #### from module 模块中的组件都可以使用注入的服务 #### from component 组件及子组件可使用注入的服务 ## Interaction 数据流入组件时会调用组件的setter 并触发`ngOnChange` hook, 因此数据拦截, 验证, 日志可以在这两处处理. 基于event driven, 更倾向于后者. ### 父组件中获取子组件 #### 模板中使用 模板的子组件元素中设置局部变量代表子组件实例(加前缀`#`表示),即可调用子组件方法. eg: ```html <contact-collect (click)="collect.collectThecontact()" #collect></contact-collect> ``` 该方法的限制是 模板变量只能用在模板中, 不能用在父组件类 #### 组件类中使用 ``` ... template:` <contact-collect (click)="collectTheContact()" ></contact-collect> ` }) export class CollectionComponent{ @ViewChild(ContectCollectComponent) contactCollect: ContactCollectComponent; ... collectTheContact(){ ... } } ``` ##### decorator 获取页面元素使用`@ViewChild`, 获取内容嵌入的元素列表使用`@ContentChildren`。 ##### pick element * 通过类名. 若是自定义标签: `@ViewChild(ContectCollectComponent)`。 若是非自定义标签, 可创建Directive 来添加对应的类 ``` @Directive({selector: 'li'}) export class ListItem{} ``` * 通过html 变量需要使用 `'`包裹: `@ViewChild('collect')` ##### property class 若是自定义标签,使用对应的类; 若非自定义标签, 使用`ElementRef`。 `@ContentChildren`修饰的属性类型应包裹在集合中。如:`QueryList<ListItem>` ## 内容嵌入 某组件的样式(或样式组合)被多次使用时可用内容嵌入来打造一个相对复杂的公共组件模板 ``` @Component({ selector: 'spi-field', template:` <div> <div style="...."> <ng-content select="label"></ng-content> </div> <div style="..."> <ng-content select=".upperCase"></ng-content> </div> </div> ` }) export class SpiFieldComponent{} ``` ``` @Component({ selector: 'bank-detail', template:` <div style="...."> <ng-content select="title"></ng-content> </div> <div style="...."> <ng-content select="spi-field"></ng-content> </div> ` }) export class BankDetailComponent{} ``` ``` @Component({ selector: 'spi-entry', template:` <third-party></third-party> <bank-deail> <title>Intermediary Bank Details (SWIFT Field 56)</title> <spi-field> <label>BIC</label> <input class="upperCase"></input> </spi-field> <spi-field> <label>TypeValue</label> <bank-code class="upperCase"></bank-code> </spi-field> </bank-detail> <bank-deail> <title>Beneficiary Bank Details</title> <spi-field> <label>BIC</label> <input class="upperCase"></input> </spi-field> <spi-field> <label>TypeValue</label> <bank-code class="upperCase"></bank-code> </spi-field> </bank-detail> ` }) export class SpiEntryComponent{} ``` ## LifeCycle Angular provide a series of hooks to invoke callback funtions when event is triggered. ### ngOnChanges Invoked when property with `@Input` is updated. ### ngOnInit 组件属性的初始化放在构造函数中, 业务功能相关的初始化放在该hoot 中. ### ngDoCheck 用于变化监测, 钩子在每次变化监测发生时被调用 ### ngAfterContentInit 组件中使用`<ng-content>` 将外部内容嵌入到组件视图后调用. 在第一次`ngDoCheck` 执行后调用, 且只执行一次. ### ngAfterContentChecked 使用`<ng-content>` 嵌入内容后调用, 或每次变化监测时调用 ### ngAfterViewInit 组件视图及其子视图被创建后调用 ### ngAfterViewChecked `ngAfterViewInit` 结束后调用 或每次子组件变化监测时调用 ### ngOnDestroy 组件销毁前调用, 用于手动销毁那些不被gc自动回收的资源. eg: - 销毁已订阅的观察者事件 - 销毁绑定过的DOM 事件 - 销毁计时器(`setTimeout`, `setInterval`) ## 变化监测 Angular 提供了数据绑定功能,所以需要监测到数据的变化以更新绑定的DOM。 Anuglar 不通过捕捉对象的变动来察觉变化, 而是通过NgZone服务自己的机制去检查对象的值是否变动 ### 数据变化源头 - 用户操作. 如click, change, hover - 后端服务数据返回. - 定时任务. 如setTimeout, setInterval, requestAnimationFrame ### 通知机制 从全局`Zone`中fork 出了一份实例并拓展, 即`NgZone`. Angular 环境中注册的异步事件都在`NgZone`中 NgZone 提供了一些自定义事件 - onUnstable 单次事件启动前, 触发消息通知订阅器 - onMicrotaskEmpty 事件完成时, 通知订阅者 - onStable `onMicrotaskEmpty` 回调函数完成后, 视图变化前, 通知订阅者。(常用来做验证) ### 响应处理 每一个组件都有一个变化监测器, 组件树即变化监测树。 变化监测从根组件开始依次触发子组件的变化监测器. ### 监测类 Angular在运行时会给每个组件创建一个监测类, 该类可通过声明的`ChangeDetectorRef`类型的变量控制,以实现: * markForCheck() 标记根组件到当前组件的路径, 路径上的所有组件必须被Angular检查 * detach() 分离变化监测器(disable detect) * reattach() (enable detect) * detectChanges() 手动触发变化监测 ### 监测策略 #### Default 变化监测检查所有数据, 效率低。 #### OnPush 仅检查输入属性, 但是无法感知到`引用不变而其内容变化` 的情况, 因此array, map等传值必须用`Immutable` 对象 code: ``` @Component({ ... changeDetection: ChangeDetectionStrategy.OnPush }) export class Foo{} ``` Template === ## 数据绑定 ### 单向绑定 #### 输入 - DOM property: `[propertyName]` - HTML attribute: `[attr.attrName]` - 样式: `[class.form-group]` `[style.color]` #### 输出 * 事件: (eventName) * 显示变量(interpotation) : ``{{prop}}`` 格式化显示 : `{{prop | pipes}}`, eg : `{{wire.netAmount | amount }} ` 属性可能不存在时使用`?` : `{{spi?.reasonCode}}` ### 双向绑定 一般用于表单: * Value of `<input>` element: ```html <input [(ngModule)]="SSI.ssiName" /> ``` * property of element: ```html <div [(title)]="name"></div> ``` Directive === ## 结构指令 should start with `*` eg: `*ngIf`, `*ngFor` ## 属性指令 looks like property binding. eg:`[ngStyle]`, `[ngClass]` Service === Dependency Injection === 被注入的服务、模块及其依赖都会被Angular 自动初始化. 无需显式初始化。 每次被注入到组件providers 中的服务都是一个新的实例. 子组件通过继承父组件可使用父组件中注入的服务, 此时该服务是单例的. Router === Module === 一个模块可由多个组件、指令、路由、服务组成以提供一个完整的功能单元 ## 模块导入 子模块导入根模块后, 模块功能即被引入. ### Angular 常用module * ApplicationModule 启动相关 * CommonModule 内置命令及内置管道 * BrowserModule 浏览器运行的工具库. 已包含ApplicationModule and CommonModule * FormsModule and ReactiveFormsModule 表单相关组件指令 * RouterModule 路由相关的组件指令 * HttpModule 网络请求相关的服务 ### 路由 路径可被合并使用 ### component and directive 组件和指令被封装在子模块中, 根模块无法使用 ### Service Service in sub-module can be used by root module ## Bootstrap ### Dynamic 浏览器加载代码后编译 ``` platformBrowserDynamic().bootstrapModule(AppModule); ``` ### Static 浏览器加载编译后的文件 ``` platformBrowser().bootstrapModuleFacotry(AppModuleNgFactory); ``` ## 标签主要数据 1. declarations 当前模块可使用的视图类(view class)[^1] 1. exports 导出给外部模块使用的视图类 1. imports 导入的其他模块 1. providers 注入的服务 [^1]: view class includes component, directive and pipe Module VS Component === Consider your angular Application as a building. A building can have N number of apartments in it. An apartment is considered as a module. An Apartment can then have N number of rooms which correspond to the building blocks of an Angular application named components. Now each apartment (Module) will have rooms (Components), lifts (Services) to enable larger movement in and out the apartments, wires (Pipes) to transform around and make it useful in the apartments. You will also have places like swimming pool, tennis court which are being shared by all building residents. So these can be considered as components inside SharedModule. Unit Test === Best Practice ===

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully