日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

flask框架视图和路由_角度视图,路由和NgModule的解释

發(fā)布時(shí)間:2023/11/29 编程问答 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 flask框架视图和路由_角度视图,路由和NgModule的解释 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

flask框架視圖和路由

Angular vs AngularJS (Angular vs AngularJS)

AngularJS (versions 1.x) is a JavaScript-based open source framework. It is cross platform and is used to develop Single Page Web Application (SPWA).

AngularJS(版本1.x)是一個(gè)基于JavaScript的開源框架。 它是跨平臺(tái)的,用于開發(fā)單頁Web應(yīng)用程序(SPWA)。

AngularJS implements the MVC pattern to separate the logic, presentation, and data components. It also uses dependency injection to make use of server-side services in client side applications.

AngularJS實(shí)現(xiàn)了MVC模式以分離邏輯,表示和數(shù)據(jù)組件。 它還使用依賴注入來在客戶端應(yīng)用程序中利用服務(wù)器端服務(wù)。

Angular (versions 2.x and up) is a Typescript-based open source framework used to develop front-end web applications. Angular has the following features like generics, static-typing, dynamic loading, and also some ES6 features.

Angular(2.x及更高版本)是基于Typescript的開源框架,用于開發(fā)前端Web應(yīng)用程序。 Angular具有以下功能,例如泛型,靜態(tài)鍵入,動(dòng)態(tài)加載以及某些ES6功能。

版本記錄 (Version History)

Google released the initial version of AngularJS on October 20,2010. The first stable release of AngularJS was on December 18, 2017 of version 1.6.8.

Google于2010年10月20日發(fā)布了AngularJS的初始版本。 AngularJS的第一個(gè)穩(wěn)定版本于1.6.8版于2017年12月18日發(fā)布。

The Angular 2.0 release took place on September 22 2014 at the ng-Europe conference.

Angular 2.0版本于2014年9月22日在ng-Europe會(huì)議上發(fā)布。

After some modifications, Angular 4.0 was released in December 2016. Angular 4 is backward compatible with Angular 2.0. The HttpClient library is one of the new features of Angular 4.0.

經(jīng)過一些修改,Angular 4.0于2016年12月發(fā)布。Angular4向后兼容Angular 2.0。 HttpClient庫是Angular 4.0的新功能之一。

Angular 5 release was on November 1, 2017. Support for progressive web apps (PWAs) ?was one of the improvements to Angular 4.0.

Angular 5發(fā)布于2017年11月1日。對(duì)漸進(jìn)式Web應(yīng)用程序(PWA)的支持是對(duì)Angular 4.0的改進(jìn)之一。

And finally, Angular 6 was released in May 2018. The latest stable version is 6.1.9

最后,Angular 6于2018年5月發(fā)布。最新的穩(wěn)定版本是6.1.9。

如何安裝 (How to install it)

We can add Angular either by referencing the sources available or downloading the framework.

我們可以通過引用可用的源代碼或下載框架來添加Angular。

AngularJS: We can add AngularJS (Angular 1.x versions) by referencing the Content Delivery Network from Google.

AngularJS:我們可以通過引用Google的內(nèi)容交付網(wǎng)絡(luò)來添加AngularJS(Angular 1.x版本)。

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.6.4/angular.min.js"></script>

Download/install: We can download the framework with npm, Bower, or composer

下載/安裝:我們可以使用npm,Bower或composer下載框架

AngularJS 1.x:

Angular JS 1.x

npm

npm

npm install angular

Then add a <script> to your index.html:

然后在您的index.html添加<script> :

<script src="/node_modules/angular/angular.js"></script>

bower

涼亭

bower install angular

Then add a <script> to your index.html:

然后在您的index.html添加<script> :

<script src="/bower_components/angular/angular.js"></script>

Angular:

角度:

For more information regarding the documentation, refer to the official site of AngularJS.

有關(guān)文檔的更多信息,請(qǐng)參考AngularJS的官方網(wǎng)站。

You can install Angular 2.x and other versions by following the steps from the official documentation of Angular.

您可以通過以下從官方文檔中的步驟安裝角2.x和其他版本的角 。

Now let's learn a bit more about Angular, shall we?

現(xiàn)在讓我們進(jìn)一步了解Angular,可以嗎?

介紹 (Introduction)

Views offer a necessary layer of abstraction. They keep Angular independent of platform specific utilities. As a cross-platform technology, Angular uses its views to connect with the platform.

視圖提供了必要的抽象層。 它們使Angular獨(dú)立于特定于平臺(tái)的實(shí)用程序。 作為一種跨平臺(tái)技術(shù),Angular使用其視圖來連接平臺(tái)。

For every element in Angular’s template HTML, there is a corresponding view. Angular recommends interacting with the platforms through these views. While direct manipulation is still possible, Angular warns against it. Angular offers its own application programming interface (API) to replace the native manipulations.

對(duì)于Angular模板HTML中的每個(gè)元素,都有一個(gè)對(duì)應(yīng)的視圖。 Angular建議通過這些視圖與平臺(tái)進(jìn)行交互。 盡管仍然可以進(jìn)行直接操縱,但Angular警告它。 Angular提供了自己的應(yīng)用程序編程接口(API)來代替本地操作。

Shunning views for platform-specific API has its consequences. When developing Angular in a web browser, elements exist in two places: the DOM and the view. Messing only with the DOM does not impact the view.

特定于平臺(tái)的API的回避視圖會(huì)產(chǎn)生后果。 在Web瀏覽器中開發(fā)Angular時(shí),元素存在于兩個(gè)位置:DOM和視圖。 僅使用DOM不會(huì)影響視圖。

Since Angular does not interface with the platform, this creates a discontinuity. Views should mirror the platform one-to-one. Otherwise Angular wastes resources managing elements that mismatch it. This is terrible in the event of deleted elements.

由于Angular不與平臺(tái)交互,因此會(huì)造成不連續(xù)。 視圖應(yīng)該一對(duì)一地反映平臺(tái)。 否則,Angular會(huì)浪費(fèi)與之不匹配的資源管理元素。 在刪除元素的情況下,這很糟糕。

These sorts of discrepancies make views appear unnecessary. Never forget that Angular is a universal development platform above all. Views are a necessary abstraction for this end.

這些差異使視圖顯得不必要。 永遠(yuǎn)不要忘記Angular首先是一個(gè)通用的開發(fā)平臺(tái)。 為此,視圖是必要的抽象。

By adhering to views, Angular applications will function across all supported development platforms. Platforms include the Web, Android, and Apple iOS.

通過遵循視圖,Angular應(yīng)用程序?qū)⒃谒惺苤С值拈_發(fā)平臺(tái)上運(yùn)行。 平臺(tái)包括Web,Android和Apple iOS。

注意 (Note)

From here-on, this article assumes a web browser environment. Feel free to mentally replace the DOM with something more applicable to your preferred platform.

從現(xiàn)在開始,本文假設(shè)使用Web瀏覽器環(huán)境。 隨意用更適合您喜歡的平臺(tái)的東西替換DOM。

什么是視圖? (What are Views?)

Views are almost like their own virtual DOM. Each view contains a reference to a corresponding section of the DOM. Inside a view are nodes that mirror what is in the this section. Angular assigns one view node per DOM element. Each node holds a reference to a matching element.

視圖幾乎就像它們自己的虛擬DOM。 每個(gè)視圖都包含對(duì)DOM相應(yīng)部分的引用。 視圖內(nèi)部是反映本節(jié)內(nèi)容的節(jié)點(diǎn)。 Angular為每個(gè)DOM元素分配一個(gè)視圖節(jié)點(diǎn)。 每個(gè)節(jié)點(diǎn)都有對(duì)匹配元素的引用。

When Angular checks for changes, it checks the views. Angular avoids the DOM under the hood. The views reference the DOM on its behalf. Other mechanisms are in place to ensure that view changes render to the DOM. Conversely, changes to the DOM do not affect the views.

Angular檢查更改時(shí),將檢查視圖。 Angular避免了幕后的DOM。 視圖代表DOM引用DOM。 還有其他機(jī)制可以確保視圖更改呈現(xiàn)給DOM。 相反,對(duì)DOM的更改不會(huì)影響視圖。

Again, views are common across all development platforms besides the DOM. Even if developing for one platform, views are still considered best practice. They guarantee Angular has a correct interpretation of the DOM.

同樣,視圖在DOM之外的所有開發(fā)平臺(tái)上都是通用的。 即使為一個(gè)平臺(tái)開發(fā),視圖仍然被認(rèn)為是最佳實(shí)踐。 它們保證Angular對(duì)DOM有正確的解釋。

Views may not exist on third-party libraries. Direct DOM manipulation is an escape hatch for this kind of scenario. Granted, do not expect the application to function cross-platform.

第三方庫上可能不存在視圖。 對(duì)于這種情況,直接DOM操作是一種逃生方法。 當(dāng)然,不要期望應(yīng)用程序可以跨平臺(tái)運(yùn)行。

視圖類型 (Types of Views)

There are two main types of views: embedded and host.

視圖有兩種主要類型:嵌入式視圖和主機(jī)視圖。

There also exists view containers. They hold embedded and host views and are often referred to as simple “views”.

還存在視圖容器。 它們具有嵌入式和宿主視圖,通常稱為簡(jiǎn)單“視圖”。

Every @Component class registers a view container (view) with Angular. New components generate a custom selector targeting a certain DOM element. The view attaches to that element wherever it appears. Angular now knows the component exists looking at the view model.

每個(gè)@Component類都向Angular注冊(cè)一個(gè)視圖容器(視圖)。 新組件會(huì)生成針對(duì)某個(gè)DOM元素的自定義選擇器。 該視圖無論出現(xiàn)在何處都將附加到該元素。 現(xiàn)在,Angular通過查看視圖模型知道組件存在。

Host views attach to components created dynamically with factories. Factories provide a blueprint for view instantiation. That way the application can instantiate the component’s host view during runtime. A host view attaches to a component’s wrapper per its instantiation. This view stores data describing conventional component capabilities.

主機(jī)視圖將附加到使用工廠動(dòng)態(tài)創(chuàng)建的組件。 工廠提供了視圖實(shí)例化的藍(lán)圖。 這樣,應(yīng)用程序可以在運(yùn)行時(shí)實(shí)例化組件的主機(jī)視圖。 主機(jī)視圖根據(jù)其實(shí)例化附加到組件的包裝器。 此視圖存儲(chǔ)描述常規(guī)組件功能的數(shù)據(jù)。

<ng-template></ng-template> is a akin to the HTML5 <template></template> element. Angular’s ng-template works with embedded views. These views do not attach to DOM elements unlike host views. They are identical to host views in that they both types exist inside of view containers.

<ng-template></ng-template>類似于HTML5 <template></template>元素。 Angular的ng-template適用于嵌入式視圖。 與宿主視圖不同,這些視圖不會(huì)附加到DOM元素。 它們與主機(jī)視圖相同,因?yàn)樗鼈兌即嬖谟谝晥D容器內(nèi)部。

Keep in mind, ng-template is not a DOM element. It gets commented out later leaving nothing but the embedded view nodes behind.

請(qǐng)記住, ng-template不是DOM元素。 稍后將其注釋掉,只剩下嵌入式視圖節(jié)點(diǎn)。

The difference depends on input data; embedded views store no component data. They store a series of elements as nodes comprising its template. The template makes up all the innerHTML of ng-template. Each element within the embedded view is its own separate view node.

差異取決于輸入數(shù)據(jù)。 嵌入式視圖不存儲(chǔ)任何組件數(shù)據(jù)。 它們將一系列元素存儲(chǔ)為組成其模板的節(jié)點(diǎn)。 模板構(gòu)成了ng-template所有innerHTML。 嵌入式視圖中的每個(gè)元素都是其自己?jiǎn)为?dú)的視圖節(jié)點(diǎn)。

主機(jī)視圖和容器 (Host Views and Containers)

Host views host dynamic components. View containers (views) attach automatically to elements already in the template. Views can attach to any element beyond what is unique to component classes.

主機(jī)視圖承載動(dòng)態(tài)組件。 視圖容器(視圖)自動(dòng)附加到模板中已存在的元素。 視圖可以附加到任何組件類之外的元素。

Think of the traditional method of component generation. It begins by creating a class, decorating it with @Component, and filling in metadata. This approach occurs for any pre-defined component element of the template.

想想傳統(tǒng)的組件生成方法。 首先創(chuàng)建一個(gè)類,用@Component裝飾它,然后填充元數(shù)據(jù)。 對(duì)于模板的任何預(yù)定義組件元素,都會(huì)發(fā)生這種方法。

Try using the Angular command-line interface (CLI) command: ng generate component [name-of-component]. It yields the following.

嘗試使用Angular命令行界面(CLI)命令: ng generate component [name-of-component] 。 它產(chǎn)生以下內(nèi)容。

import { Component, OnInit } from '@angular/core';@Component({selector: 'app-example',templateUrl: './example.component.html',styleUrls: ['./example.component.css'] }) export class ExampleComponent implements OnInit {constructor() { }ngOnInit() { } }

This creates the component with the selector app-example. This attaches a view container to <app-example></app-example> in the template. If this were the root of the application, its view would encapsulate all other views. The root view marks the beginning of the application from Angular’s perspective.

這將使用選擇器app-example創(chuàng)建組件。 這會(huì)將視圖容器附加到模板中的<app-example></app-example> 。 如果這是應(yīng)用程序的根,則其視圖將封裝所有其他視圖。 從Angular的角度來看,根視圖標(biāo)志著應(yīng)用程序的開始。

Creating components dynamically and registering them in the Angular view model takes a few extra steps. Structural directives help manage dynamic content (*ngIf, *ngFor, and *ngSwitch…). Directives do not scale to bigger applications however. Too many structural directives complicates the template.

動(dòng)態(tài)創(chuàng)建組件并將其注冊(cè)到Angular視圖模型中需要花費(fèi)一些額外的步驟。 結(jié)構(gòu)化指令有助于管理動(dòng)態(tài)內(nèi)容( *ngIf, *ngFor, and *ngSwitch… )。 但是,指令無法擴(kuò)展到更大的應(yīng)用程序。 太多的結(jié)構(gòu)指令使模板復(fù)雜化。

This is where instantiating components from existing class logic comes in handy. These components need to create a host view that can insert into the view model. Host views holds data for components so that Angular recognizes their structural purpose.

這是從現(xiàn)有類邏輯實(shí)例化組件的地方。 這些組件需要?jiǎng)?chuàng)建一個(gè)可以插入視圖模型的宿主視圖。 宿主視圖保存組件的數(shù)據(jù),以便Angular識(shí)別其結(jié)構(gòu)目的。

主機(jī)視圖續(xù) (Host Views Continued)

Every component has a class definition. Yet JavaScript does not support classes. Classes are syntactic sugar. They produce functions containing component factories instead.

每個(gè)組件都有一個(gè)類定義。 但是JavaScript不支持類。 類是語法糖。 它們產(chǎn)生包含組件工廠的函數(shù)。

Factories act as blueprints for host views. They build views to interface with Angular on behalf of their components. Host views attach to DOM elements. Technically any element is OK but the most common target is <ng-component></ng-component>.

工廠充當(dāng)主機(jī)視圖的藍(lán)圖。 他們構(gòu)建視圖以代表其組件與Angular交互。 主機(jī)視圖附加到DOM元素。 從技術(shù)上講,任何元素都可以,但最常見的目標(biāo)是<ng-component></ng-component> 。

A view container (view) for holding views must first exist. <ng-container></ng-container> is a great place to attach a view container. View containers are the same type of views that also apply to template class elements.

首先必須存在用于保存視圖的視圖容器(視圖)。 <ng-container></ng-container>是附加視圖容器的好地方。 視圖容器是與視圖類型相同的視圖,也適用于模板類元素。

A few helpers and references from @angular/core provide the other needed utilities. The following example puts it all together.

@angular/core一些幫助程序和參考提供了其他所需的實(shí)用程序。 以下示例將所有內(nèi)容放在一起。

// another.component.tsimport { Component } from '@angular/core';@Component({template: `<h1>Another Component Content</h1><h3>Dynamically Generated!</h3>` }) export class AnotherComponent { }// example.component.tsimport { AfterViewInit, Component, ViewChild, ViewContainerRef, ComponentFactoryResolver } from '@angular/core'; import { AnotherComponent } from './another.component';@Component({selector: 'app-example',template: `<h1>Application Content</h1><ng-container #container></ng-container><h3>End of Application</h3>`,entryComponents: [ AnotherComponent ] }) export class ExampleComponent implements AfterViewInit {@ViewChild("container", { read: ViewContainerRef }) ctr: ViewContainerRef;constructor(private resolve: ComponentFactoryResolver) { }ngAfterViewInit() {const factory = this.resolve.resolveComponentFactory(AnotherComponent);this.ctr.createComponent(factory);} }

Assume AnotherComponent and ExampleComponent are both declared under the same module. AnotherComponent is a simple class component dynamically added into ExampleComponent’s view. ExampleComponent’s entryComponents metadata must contain AnotherComponent for bootstrapping.

假設(shè)AnotherComponent和ExampleComponent都在同一模塊下聲明。 AnotherComponent是一個(gè)動(dòng)態(tài)添加到ExampleComponent的視圖中的簡(jiǎn)單類組件。 ExampleComponent的entryComponents元數(shù)據(jù)必須包含用于引導(dǎo)的 AnotherComponent。

While ExampleComponent is a part of the template, AnotherComponent remains detached. It dynamically renders into the template from ExampleComponent.

雖然ExampleComponent是模板的一部分,但是AnotherComponent仍然是分離的。 它從ExampleComponent動(dòng)態(tài)地渲染到模板中。

There are two view containers present: <app-example></app-example> and <ng-container></ng-container>. The host view for this example will insert into ng-container.

存在兩個(gè)視圖容器: <app-example></app-example>和<ng-container></ng-container> 。 此示例的宿主視圖將插入ng-container 。

The AfterViewInit lifecycle hook fires after the @ViewChild queries complete. Using the template reference variable #container, the @ViewChild references ng-container as ctr.

@ViewChild查詢完成后,將觸發(fā)AfterViewInit生命周期掛鉤。 使用模板引用變量 #container @ViewChild , @ViewChild將ng-container引用為ctr 。

ViewContainerRef is the type of reference for view containers (views). ViewContainerRef references a view that supports the insertion of other views. ViewContainerRef contains more methods for managing its contained views.

ViewContainerRef是視圖容器(視圖)的引用類型。 ViewContainerRef引用一個(gè)支持其他視圖插入的視圖。 ViewContainerRef包含更多方法來管理其包含的視圖。

Through dependency injection, the constructor instantiates an instance of Angular’s ComponentFactoryResolver service. This service extracts the the factory function (host view blueprint) of AnotherComponent.

通過依賴注入,構(gòu)造函數(shù)實(shí)例化Angular的ComponentFactoryResolver服務(wù)的實(shí)例。 此服務(wù)提取AnotherComponent的工廠功能(主機(jī)視圖藍(lán)圖)。

The single argument of createComponent requires a factory. The createComponent function derives from ViewContainerRef. It instantiates AnotherComponent under a host view derived from the component’s factory.

createComponent的單個(gè)參數(shù)需要一個(gè)工廠。 createComponent函數(shù)從ViewContainerRef派生。 它在派生自組件工廠的主機(jī)視圖下實(shí)例化AnotherComponent。

The host view then inserts into the view container. <ng-component></ng-component> wraps the component inside of the view container. It has attached to it the aforementioned host view. ng-component is the host view’s connection with the DOM.

然后,宿主視圖將插入到視圖容器中。 <ng-component></ng-component>將組件包裝在視圖容器內(nèi)部。 它已附加上述主機(jī)視圖。 ng-component是主機(jī)視圖與DOM的連接。

There are other ways create a host view dynamically from a component. Other ways often focus on optimization.

還有其他方法可以從組件動(dòng)態(tài)創(chuàng)建主機(jī)視圖。 其他方法通常專注于優(yōu)化 。

The ViewContainerRef holds a powerful API. It can manage any number of views either host or embedded within its view. The API includes view operations such as insert, move, and delete. This lets you manipulate the DOM through Angular’s view model. This is best practice so that Angular and the DOM match each other.

ViewContainerRef擁有強(qiáng)大的API。 它可以管理宿主視圖或嵌入在其視圖中的任意數(shù)量的視圖。 該API包括視圖操作,例如插入,移動(dòng)和刪除。 這使您可以通過Angular的視圖模型來操作DOM。 最佳做法是使Angular和DOM相互匹配。

嵌入式視圖 (Embedded Views)

Note: embedded views attach to other views no added input. Host views attach to a DOM element with input data from its host view describing it as a component.

注意:嵌入式視圖附加到其他視圖,沒有添加輸入。 主機(jī)視圖附加到DOM元素,并帶有來自其主機(jī)視圖的輸入數(shù)據(jù),將其描述為組件。

Structural directives create an ng-template surrounding a chunk of HTML content. The directive’s host element has a view container attached. This make it so that the content can conditionally render into its intended layout.

結(jié)構(gòu)化指令會(huì)在大量HTML內(nèi)容周圍創(chuàng)建一個(gè)ng-template 。 指令的host元素具有連接的視圖容器。 這樣可以使內(nèi)容可以有條件地呈現(xiàn)為其預(yù)期的布局。

The ng-template holds embedded view nodes representing each element within its innerHTML. ng-template is by no means a DOM element. It comments itself out. The tags define the extend of its embedded view.

ng-template包含表示其innerHTML中每個(gè)元素的嵌入式視圖節(jié)點(diǎn)。 ng-template絕不是DOM元素。 它自行注釋掉。 標(biāo)簽定義其嵌入式視圖的擴(kuò)展。

嵌入式視圖續(xù) (Embedded Views Continued)

Instantiating an embedded view requires no external resources beyond its own reference. The @ViewChild query can fetch that.

實(shí)例化嵌入式視圖不需要其引用之外的任何外部資源。 @ViewChild查詢可以獲取該信息。

With the template reference, calling createEmbeddedView from it does the trick. The innerHTML of the reference becomes its own embedded view instance.

使用模板引用,從中調(diào)用createEmbeddedView可以解決問題。 引用的innerHTML成為其自己的嵌入式視圖實(shí)例。

In the next example, <ng-container></ng-container> is a view container. ng-container gets commented out during compilation just like ng-template. Thus it provides an outlet for inserting the embedded view while keeping the DOM lean.

在下一個(gè)示例中, <ng-container></ng-container>是一個(gè)視圖容器。 ng-container就像ng-template一樣在編譯過程ng-container被注釋掉。 因此,它提供了用于在保持DOM精簡(jiǎn)的同時(shí)插入嵌入式視圖的出口。

The embedded view template inserts at the layout location of ng-container. This newly inserted view has no additional view encapsulation besides the view container. Remember how that differs from host views (host views attach to their ng-component element wrapper).

嵌入式視圖模板將插入ng-container的布局位置。 這個(gè)新插入的視圖除視圖容器外沒有其他視圖封裝。 記住與主機(jī)視圖有何不同(主機(jī)視圖附加到其ng-component元素包裝器)。

import { Component, AfterViewInit, ViewChild, ViewContainerRef, TemplateRef } from '@angular/core';@Component({selector: 'app-example',template: `<h1>Application Content</h1><ng-container #container></ng-container> <!-- embed view here --><h3>End of Application</h3><ng-template #template><h1>Template Content</h1><h3>Dynamically Generated!</h3></ng-template>` }) export class ExampleComponent implements AfterViewInit {@ViewChild("template", { read: TemplateRef }) tpl: TemplateRef<any>;@ViewChild("container", { read: ViewContainerRef }) ctr: ViewContainerRef;constructor() { }ngAfterViewInit() {const view = this.tpl.createEmbeddedView(null);this.ctr.insert(view);} }

@ViewChild queries for the template reference variable #template. This provides a template reference of type TemplateRef. TemplateRef holds the createEmbeddedView function. It instantiates the template as an embedded view.

@ViewChild查詢模板引用變量 #template 。 這提供類型的模板參考TemplateRef 。 TemplateRef擁有createEmbeddedView函數(shù)。 它將模板實(shí)例化為嵌入式視圖。

The single argument of createEmbeddedView is for context. If you wanted to pass in additional metadata, you could do it here as an object. The fields should match up with the ng-template attributes (let-[context-field-key-name]=“value”). Passing null indicates no extra metadata is necessary.

createEmbeddedView的單個(gè)參數(shù)用于上下文。 如果您想傳遞其他元數(shù)據(jù),則可以在此處作為對(duì)象來進(jìn)行傳遞。 這些字段應(yīng)與ng-template屬性匹配( let-[context-field-key-name]=“value” )。 傳遞null表示不需要額外的元數(shù)據(jù)。

A second @ViewChild query provides a reference to ng-container as a ViewContainerRef. Embedded views only attach to other views, never the DOM. The ViewContainerRef references the view that takes in the embedded view.

第二個(gè)@ViewChild查詢提供對(duì)ng-container的引用作為ViewContainerRef 。 嵌入式視圖僅附加到其他視圖,而不附加到DOM。 ViewContainerRef引用嵌入視圖中的視圖。

An embedded view may also insert into the component view of <app-example></app-example>. This approach positions the view at the very end of ExampleComponent’s view. In this example however, we want the content to show up in the very middle where ng-container sits.

嵌入式視圖也可以插入<app-example></app-example>的組件視圖中。 這種方法將視圖放置在ExampleComponent視圖的最末端。 但是,在此示例中,我們希望內(nèi)容顯示在ng-container所在的中間位置。

The ViewContainerRef insert function inserts the embedded view into the ng-container. The view content shows ups in the intended location right in the middle of ExampleComponent’s view.

ViewContainerRef insert函數(shù)將嵌入的視圖插入ng-container 。 視圖內(nèi)容將顯示在ExampleComponent視圖中間的預(yù)期位置。

結(jié)論 (Conclusion)

Manipulating the DOM with platform specific methods is not recommended. Creating and managing a tight set of views keeps Angular and the DOM on the same page. Updating the views informs Angular of the current state of the DOM. Updates to the views also carry over into what the DOM displays.

不建議使用平臺(tái)特定的方法來操作DOM。 創(chuàng)建和管理一組緊密的視圖會(huì)使Angular和DOM保持在同一頁面上。 更新視圖會(huì)通知Angular DOM當(dāng)前狀態(tài)。 對(duì)視圖的更新也會(huì)保留到DOM顯示的內(nèi)容中。

Angular provides a flexible API for view interaction. Developing platform independent applications is possible thanks to this level of abstraction. Of course, the temptation to fallback on platform dependent strategies persists. Unless you have a very good reason not to, try to stick with the views API Angular provides. This will yield predictable results across all platforms.

Angular為視圖交互提供了一個(gè)靈活的API。 由于這種抽象水平,開發(fā)與平臺(tái)無關(guān)的應(yīng)用程序成為可能。 當(dāng)然,回退依賴于平臺(tái)的策略的誘惑仍然存在。 除非您有很好的理由不這樣做,否則請(qǐng)嘗試使用API?? Angular提供的視圖。 這將在所有平臺(tái)上產(chǎn)生可預(yù)測(cè)的結(jié)果。

角度布線 (Routing in Angular)

Routing is essential. Many modern web applications host too much information for one page. Users should not have to scroll through an entire application’s worth of content either. An application needs to split itself into distinguishable sections.

路由至關(guān)重要。 許多現(xiàn)代的Web應(yīng)用程序?yàn)橐豁摮休d太多信息。 用戶也不必滾動(dòng)瀏覽整個(gè)應(yīng)用程序的內(nèi)容。 應(yīng)用程序需要將自身拆分為不同的部分。

Users prioritize necessary information. Routing helps them find the application section with such information. Any other information useful to other users may exist on an entirely separate route. With routing, both users can find what they need quickly. Irrelevant details stay obscured behind irrelevant routes.

用戶優(yōu)先考慮必要的信息。 路由幫助他們找到帶有此類信息的應(yīng)用程序部分。 對(duì)其他用戶有用的任何其他信息都可以存在于完全獨(dú)立的路徑上。 通過路由,兩個(gè)用戶都可以快速找到他們需要的東西。 不相關(guān)的細(xì)節(jié)在不相關(guān)的路線后面被遮蓋。

Routing excels at sorting and restricting access to application data. Sensitive data should never display to unauthorized users. Between every route the application may intervene. It can examine a user’s session for authentication purposes. This examination determines what the route renders if it should render at all. Routing gives developers the perfect chance to verify a user before proceeding.

路由擅長于排序和限制對(duì)應(yīng)用程序數(shù)據(jù)的訪問。 敏感數(shù)據(jù)絕不能顯示給未經(jīng)授權(quán)的用戶。 在每條路線之間,應(yīng)用程序都可能會(huì)介入。 它可以檢查用戶的會(huì)話以進(jìn)行身份??驗(yàn)證。 該檢查確定路線是否應(yīng)該渲染。 路由為開發(fā)人員提供了在繼續(xù)操作之前驗(yàn)證用戶的絕佳機(jī)會(huì)。

Creating a list of routes promotes organization as well. In terms of development, it keeps the developer thinking in distinguishable sections. Users benefit from this too, but more-so developers when navigating the application code. A list of programmatic routers paints an accurate model of the application’s front end.

創(chuàng)建路由列表也可以促進(jìn)組織。 在開發(fā)方面,它使開發(fā)人員可以在可區(qū)分的部分中進(jìn)行思考。 用戶也從中受益,但是開發(fā)人員在瀏覽應(yīng)用程序代碼時(shí)也會(huì)從中受益。 一系列編程路由器描繪了應(yīng)用程序前端的準(zhǔn)確模型。

As for Angular, routing takes up its own entire library within the framework. All modern front-end frameworks support routing, and Angular is no different. Routing happens from the client-side using either hash or location routing. Both styles allow the client to manage its own routes. No additional assistance from the server is necessary past the initial request.

至于Angular,路由在框架內(nèi)占用了它自己的整個(gè)庫。 所有現(xiàn)代的前端框架都支持路由,而Angular也不例外。 使用散列或位置路由從客戶端進(jìn)行路由。 兩種樣式都允許客戶端管理自己的路由。 在初始請(qǐng)求之后,無需服務(wù)器的其他幫助。

The web browser rarely refreshes using client-side routing. Web browser utilities such as bookmarks, history, and the address bar still work despite no refreshing. This makes for a slick routing experience that does not mess up the browser. No more jumpy page reloads while routing to a different page.

Web瀏覽器很少使用客戶端路由刷新。 盡管沒有刷新,諸如書簽,歷史記錄和地址欄之類的Web瀏覽器實(shí)用程序仍然可以使用。 這提供了流暢的路由體驗(yàn),不會(huì)干擾瀏覽器。 路由到其他頁面時(shí),不再需要重新加載頁面。

Angular adds on a layer of abstraction over the core technologies used for routing. This article intends to explain this abstraction. There exists two routing strategies in Angular: path location and hash. This article focuses on the path location strategy since its the default option.

Angular在用于路由的核心技術(shù)上增加了一層抽象。 本文旨在解釋這種抽象。 Angular中存在兩種路由策略:路徑位置和哈希。 本文重點(diǎn)介紹路徑定位策略,因?yàn)樗悄J(rèn)選項(xiàng)。

Plus, path location may deprecate hash routing following the full release of Angular Universal. Regardless, the two strategies are very similar in implementation. Learning one learns the other. Time to get started!

另外,在Angular Universal全面發(fā)布之后,路徑位置可能會(huì)棄用哈希路由。 無論如何,這兩種策略在實(shí)現(xiàn)上非常相似。 學(xué)習(xí)一個(gè)學(xué)習(xí)另一個(gè)。 是時(shí)候開始了!

路由器模塊設(shè)置 (RouterModule Setup)

Routing utilities export with RouterModule available from @angular/router. It is not part of the core library since not all applications require routing. The most conventional way to introduce routing is as its own feature module.

路由實(shí)用程序可通過@angular/router RouterModule導(dǎo)出。 它不是核心庫的一部分,因?yàn)椴⒎撬袘?yīng)用程序都需要路由。 引入路由的最傳統(tǒng)方法是作為其自身的功能模塊 。

As route complexity grows, having it as its own module will promote the root module’s simplicity. Keeping it stupid simple without compromising functionality constitutes good design for modules.

隨著路由復(fù)雜度的增加,將其作為自己的模塊將促進(jìn)根模塊的簡(jiǎn)單性。 在不影響功能的情況下保持愚蠢的簡(jiǎn)單性構(gòu)成了模塊的良好設(shè)計(jì)。

import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router';import { AComponent } from '../../components/a/a.component'; import { BComponent } from '../../components/b/b.component';// an array of soon-to-be routes! const routes: Routes = [];@NgModule({imports: [ RouterModule.forRoot(routes) ],exports: [ RouterModule ] }) export class AppRoutingModule { }

.forRoot(...) is a class function available from the RouterModule class. The function accepts an array of Route objects as Routes. .forRoot(...) configures routes for eager-loading while its alternative .forChild(...) configures for lazy-loading.

.forRoot(...)是RouterModule類中可用的類函數(shù)。 該函數(shù)接受Route對(duì)象數(shù)組作為Routes 。 .forRoot(...)配置路由以進(jìn)行.forChild(...)加載,而其替代.forChild(...)配置為延遲加載。

Eager-loading meaning the routes load their content into the application from the get-go. Lazy-loading happens on-demand. The focus of this article is eager-loading. It is the default approach for loading in an application. The RouterModule class definition looks something like the next block of code.

急切加載意味著路由從一開始就將其內(nèi)容加載到應(yīng)用程序中。 延遲加載按需進(jìn)行。 本文的重點(diǎn)是急切加載。 這是在應(yīng)用程序中加載的默認(rèn)方法。 RouterModule類定義類似于下一個(gè)代碼塊。

@NgModule({// … lots of metadata ... }) export class RouterModule {forRoot(routes: Routes) {// … configuration for eagerly loaded routes …}forChild(routes: Routes) {// … configuration for lazily loaded routes …} }

Do not worry about the configuration details the example omits with comments. Having a general understanding will do for now.

不必?fù)?dān)心示例中帶有注釋的配置詳細(xì)信息。 大致了解現(xiàn)在就可以了。

Notice how AppRoutingModule imports the RouterModule while also exporting it. This makes sense given AppRoutingModule is a feature module. It imports into the root module as a feature module. It exposes RouterModule directives, interfaces, and services to the root component tree.

請(qǐng)注意AppRoutingModule如何導(dǎo)入RouterModule并同時(shí)將其導(dǎo)出。 鑒于AppRoutingModule是功能模塊,這是有道理的。 它將作為功能模塊導(dǎo)入到根模塊中。 它將RouterModule指令,接口和服務(wù)公開給根組件樹。

This explains why AppRoutingModule must export RouterModule. It does so for the sake of the root module’s underlying component tree. It needs access to those routing utilities!

這解釋了為什么AppRoutingModule必須導(dǎo)出RouterModule。 這樣做是為了根模塊的基礎(chǔ)組件樹。 它需要訪問那些路由實(shí)用程序!

import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core';import { AppComponent } from './app.component'; import { AComponent } from './components/a/a.component'; import { BComponent } from './components/b/b.component'; import { AppRoutingModule } from './modules/app-routing/app-routing.module';@NgModule({declarations: [AppComponent,AComponent,BComponent],imports: [AppRoutingModule, // routing feature moduleBrowserModule],providers: [],bootstrap: [ AppComponent ] }) export class AppModule { }

The AppRoutingModule token imports from the very top. Its token inserts into the root module’s imports array. The root component tree may now utilize the RouterModule library. That includes its directives, interfaces, and services as already mentioned. Big thanks goes to AppRoutingModule for exporting RouterModule!

AppRoutingModule令牌從最頂部導(dǎo)入。 它的令牌插入到根模塊的imports數(shù)組中。 根組件樹現(xiàn)在可以利用RouterModule庫。 如前所述,這包括其指令,接口和服務(wù)。 非常感謝AppRoutingModule導(dǎo)出RouterModule!

The RouterModule utilities will come in handy for the root’s components. The basic HTML for AppComponent makes use of one directive: router-outlet.

RouterModule實(shí)用程序?qū)?duì)根目錄的組件派上用場(chǎng)。 AppComponent的基本HTML使用一個(gè)指令: router-outlet 。

<!-- app.component.html --><ul><!-- routerLink(s) here --> </ul> <router-outlet></router-outlet> <!-- routed content appends here (AFTER THE ELEMENT, NOT IN IT!) -->

routerLink is an attribute directive of RouterModule. It will attach to each element of <ul></ul> once the routes are setup. router-outlet is a component directive with interesting behavior. It acts more as a marker for displaying routed content. Routed content results from navigation to a specific route. Usually that means a single component as configured in AppRoutingModule

routerLink是routerLink的屬性指令。 設(shè)置路由后,它將附加到<ul></ul>每個(gè)元素。 router-outlet是具有有趣行為的組件指令。 它更多地用作顯示路由內(nèi)容的標(biāo)記。 路由內(nèi)容是從導(dǎo)航到特定路由的結(jié)果。 通常,這意味著在AppRoutingModule中配置的單個(gè)組件

The routed content renders right after <router-outlet></router-outlet>. Nothing renders inside of it. This does not make too much of a considerable difference. That said, do not expect router-outlet to behave like a container for routed content. It is merely a marker for appending routed content to the Document Object Model (DOM).

路由的內(nèi)容在<router-outlet></router-outlet>之后呈現(xiàn)。 里面什么也沒有。 這并沒有太大的區(qū)別。 就是說,不要指望router-outlet表現(xiàn)得像是路由內(nèi)容的容器。 它只是用于將路由內(nèi)容附加到文檔對(duì)象模型(DOM)的標(biāo)記。

基本路由 (Basic Routing)

The previous section establishes the basic setup for routing. Before actual routing can happen, a few more things must be addressed

上一節(jié)建立了路由的基本設(shè)置。 在實(shí)際的路由發(fā)生之前,還必須解決一些其他問題

The first question to address is what routes will this application consume? Well, there are two components: AComponent and BComponent. Each one should have its own route. They can render from AppComponent’s router-outlet depending on the current route location.

要解決的第一個(gè)問題是此應(yīng)用程序?qū)⑾哪男┞酚?#xff1f; 好,有兩個(gè)組件:AComponent和BComponent。 每個(gè)人都應(yīng)該有自己的路線。 它們可以根據(jù)當(dāng)前路線位置從AppComponent的router-outlet進(jìn)行渲染。

The route location (or path) defines what appends to a website’s origin (e.g. http://localhost:4200) through a series of slashes (/).

路由位置(或路徑)定義了通過一系列斜杠( / )附加到網(wǎng)站來源 (例如http:// localhost:4200 )的內(nèi)容。

// … same imports from before …const routes: Routes = [{path: 'A',component: AComponent},{path: 'B',component: BComponent} ];@NgModule({imports: [ RouterModule.forRoot(routes) ],exports: [ RouterModule ] }) export class AppRoutingModule { }

http://localhost:4200/A renders AComponent from AppComponent’s router-outlet. http://localhost:4200/B renders BComponent. You need a way to route to these locations without using the address bar though. An application should not rely upon a web browser’s address bar for navigation.

http://localhost:4200/A從AppComponent的router-outlet out呈現(xiàn)AComponent。 http://localhost:4200/B呈現(xiàn)BComponent。 您需要一種無需使用地址欄即可路由到這些位置的方法。 應(yīng)用程序不應(yīng)依賴Web瀏覽器的地址欄進(jìn)行導(dǎo)航。

The global CSS (Cascading Style-sheets) supplements the HTML below it. An application’s router link ought to have a pleasant appearance. This CSS applies to all other examples too.

全局CSS(層疊樣式表)補(bǔ)充了其下方HTML。 應(yīng)用程序的路由器鏈接應(yīng)具有愉悅的外觀。 該CSS也適用于所有其他示例。

/* global styles.css */ul li {cursor: pointer;display: inline-block;padding: 20px;margin: 5px;background-color: whitesmoke;border-radius: 5px;border: 1px solid black; }ul li:hover {background-color: lightgrey; }<!-- app.component.html --><ul><li routerLink="/A">Go to A!</li><li routerLink="/B">Go to B!</li> </ul> <router-outlet></router-outlet>

This is basic routing! Clicking either of the routerLink elments routes the web address. It reassigns it without refreshing the web browser. Angular’s Router maps the routed address to the Routes configured in AppRoutingModule. It matches the address to the path property of a single Route object within the array. First match always wins, so match-all routes should lie at the very end of the Routes array.

這是基本的路由! 單擊任一routerLink元素將路由該網(wǎng)址。 它會(huì)重新分配它,而不刷新Web瀏覽器。 Angular的Router將路由的地址映射到AppRoutingModule中配置的Routes 。 它將地址與數(shù)組中單個(gè)Route對(duì)象的path屬性匹配。 首次比賽總是獲勝,因此所有比賽路線都應(yīng)位于Routes數(shù)組的末尾。

Match-all routes prevent the application from crashing if it cannot match the current route. This can happen from the address bar where the user may type in any route. For this, Angular provides a wildcard path value ** that accepts all routes. This route usually renders a PageNotFoundComponent component displaying “Error 404: Page not found”.

全部匹配路由可以防止應(yīng)用程序如果無法匹配當(dāng)前路由而崩潰。 這可以從用戶可以在其中輸入任何路線的地址欄中發(fā)生。 為此,Angular提供了一個(gè)通配符路徑值** ,該值可以接受所有路由。 此路由通常會(huì)渲染一個(gè)顯示“錯(cuò)誤404:找不到頁面”的PageNotFoundComponent組件。

// … PageNotFoundComponent imported along with everything else …const routes: Routes = [{path: 'A',component: AComponent},{path: 'B',component: BComponent},{path: '',redirectTo: 'A',pathMatch: 'full'},{path: '**',component: PageNotFoundComponent} ];

The Route object containing redirectTo keeps the PageNotFoundComponent from rendering as a result of http://localhost:4200. This is the applications home route. To fix this, redirectTo reroutes the home route to http://localhost:4200/A. http://localhost:4200/A indirectly becomes the application’s new home route.

包含redirectTo的Route對(duì)象使PageNotFoundComponent不會(huì)由于http://localhost:4200而呈現(xiàn)。 這是應(yīng)用程序的本地路由。 要解決此問題, redirectTo將本地路由重新路由到http://localhost:4200/A http://localhost:4200/A間接成為應(yīng)用程序的新本地路由。

The pathMatch: 'full' tells the Route object to match against the home route (http://localhost:4200). It matches the empty path.

pathMatch: 'full'告訴Route對(duì)象與本地路由( http://localhost:4200 )匹配。 它匹配空路徑。

These two new Route objects go at the end of the array since first match wins. The last array element (path: '**') always matches, so it goes last.

由于首場(chǎng)比賽獲勝,這兩個(gè)新的Route對(duì)象位于數(shù)組的末尾。 最后一個(gè)數(shù)組元素( path: '**' )始終匹配,因此位于最后。

There is one last thing worth addressing before moving on. How does the user know where he or she is in the application relative to the current route? Sure there may be content specific to the route, but how is user supposed to make that connection? There should be some form of highlighting applied to the routerLinks. That way, the user will know which route is active for the given web page.

在繼續(xù)之前,還有最后一件事值得解決。 用戶如何知道他或她在應(yīng)用程序中相對(duì)于當(dāng)前路線的位置? 當(dāng)然,可能存在特定于該路線的內(nèi)容,但是用戶應(yīng)該如何建立該連接? 應(yīng)該對(duì)路由器鏈接應(yīng)用某種形式的突出顯示。 這樣,用戶將知道哪個(gè)路由對(duì)于給定的網(wǎng)頁是活動(dòng)的。

This is an easy fix. When you click a routerLink element, Angular’s Router assigns focus to it. This focus can trigger certain styles which provide useful feedback to the user. The routerLinkActive directive can track this focus for the developer.

這是一個(gè)簡(jiǎn)單的修復(fù)。 當(dāng)您單擊routerLink元素時(shí),Angular的Router會(huì)為其分配焦點(diǎn) 。 該焦點(diǎn)可以觸發(fā)某些樣式,這些樣式可以為用戶提供有用的反饋。 routerLinkActive指令可以為開發(fā)人員跟蹤此焦點(diǎn)。

<!-- app.component.html --><ul><li routerLink="/A" routerLinkActive="active">Go to A!</li><li routerLink="/B" routerLinkActive="active">Go to B!</li> </ul> <router-outlet></router-outlet>

The right assignment of routerLinkActive represents a string of classes. This example portrays only one class (.active), but any number of space-delimited classes may apply. When the Router assigns focus to a routerLink, the space-delimited classes apply to the host element. When the focus shifts away, the classes get removed automatically.

正確的routerLinkActive分配表示一串類。 本示例僅描繪一個(gè)類( .active ),但是可以應(yīng)用任何數(shù)量的以空格分隔的類。 當(dāng)Router將焦點(diǎn)分配給routerLink時(shí),以空格分隔的類適用于主機(jī)元素。 當(dāng)焦點(diǎn)移開時(shí),這些類將自動(dòng)刪除。

/* global styles.css */.active {background-color: lightgrey !important; }

Users can now easily recognize how the current route and the page content coincide. lightgrey highlighting applies to the routerLink matching the current route. !important ensures the highlighting overrides inline stylings.

用戶現(xiàn)在可以輕松地識(shí)別當(dāng)前路線和頁面內(nèi)容的重合方式。 lightgrey高亮適用于routerLink匹配當(dāng)前的路線。 !important確保突出顯示覆蓋內(nèi)聯(lián)樣式。

參數(shù)化路線 (Parameterized Routes)

Routes do not have to be completely hard-coded. They can contain dynamic variables referenceable from the component corresponding the Route object. These variables are declared as parameters when writing the route’s path.

路由不必完全硬編碼。 它們可以包含可從對(duì)應(yīng)于Route對(duì)象的組件引用的動(dòng)態(tài)變量。 這些變量在寫入路徑時(shí)被聲明為參數(shù)。

Route parameters are either optional or mandatory for matching a particular Route. It depends on how a route writes its parameters. Two strategies exist: matrix and traditional parameterization.

路由參數(shù)對(duì)于匹配特定Route是可選的或必需的。 這取決于路由如何寫入其參數(shù)。 存在兩種策略:矩陣和傳統(tǒng)參數(shù)化。

Traditional parameterization begins from the Routes array configured in AppRoutingModule.

傳統(tǒng)的參數(shù)化從AppRoutingModule中配置的Routes數(shù)組開始。

const routes: Routes = [// … other routes …{path: 'B',component: BComponent},{path: 'B/:parameter',component: BComponent},// … other routes … ];

Focus on the two BComponent routes. Parameterization will eventually occur in both routes.

關(guān)注兩條BComponent路線。 參數(shù)化最終將在兩條路徑中發(fā)生。

Traditional parameterization occurs in the second BComponent Route. B/:parameter contains the parameter parameter as indicated with the :. Whatever follows the colon marks the parameter’s name. The parameter parameter is necessary for the second BComponent Route to match.

傳統(tǒng)的參數(shù)化發(fā)生在第二個(gè)BComponent Route 。 B/:parameter包含parameter參數(shù),如: 。 冒號(hào)后面的所有內(nèi)容都會(huì)標(biāo)記參數(shù)的名稱。 parameter parameter是第二個(gè)BComponent Route匹配所必需的。

parameter reads in the value of whatever gets passed into the route. Routing to http://localhost:4200/B/randomValue will assign parameter the value of randomValue. This value can include anything besides another /. For example, http://localhost:4200/B/randomValue/blahBlah will not trigger the second BComponent Route. The PageNotFoundComponent renders instead.

parameter讀取傳遞到路由中的值。 路由到http://localhost:4200/B/randomValue將分配parameter的值randomValue 。 該值可以包含/以外的任何值。 例如, http://localhost:4200/B/randomValue/blahBlah將不會(huì)觸發(fā)第二個(gè)BComponent Route 。 而不是PageNotFoundComponent呈現(xiàn)。

BComponent can reference route parameters from its component class. Both approaches to parameterization (matrix and traditional) yield the same results in BComponent. Before seeing BComponent, examine the matrix form of parameterization below.

BComponent可以從其組件類中引用路由參數(shù)。 兩種參數(shù)化方法(矩陣和傳統(tǒng)方法)在BComponent中產(chǎn)生相同的結(jié)果。 在看到BComponent之前,請(qǐng)檢查下面的參數(shù)化矩陣形式。

// app.component.tsimport { Component } from '@angular/core'; import { Router } from '@angular/router';@Component({selector: 'app-root',templateUrl: './app.component.html' }) export class AppComponent {constructor(private router: Router) { }routeMatrixParam(value: string) {if (value)this.router.navigate(['B', { parameter: value }]); // matrix parameterelsethis.router.navigate(['B']);}routeAddressParam(value: string) {this.router.navigate(['B', value]);} }

Angular’s dependency injection system provides an instantiation of the Router. This lets the component programmatically route. The .navigate(...) function accepts an array of values that resolves to a routable path. Something like .navigate(['path', 'to', 'something']) resolves to http://localhost:4200/path/to/something. .navigate(...) adds path-delimiting / marks when normalizing the array into a routable path.

Angular的依賴項(xiàng)注入系統(tǒng)提供Router的實(shí)例化。 這使組件可以編程方式進(jìn)行布線。 .navigate(...)函數(shù)接受一個(gè)可解析為可路由路徑的值數(shù)組。 諸如.navigate(['path', 'to', 'something'])解析為http://localhost:4200/path/to/something 。 .navigate(...)在將數(shù)組歸一化為可路由路徑時(shí)添加了路徑.navigate(...) /標(biāo)記。

The second form of parameterization occurs in routeMatrixParam(...). See this line of code: this.router.navigate(['B', { parameter: value }]). This form of parameter is a matrix parameter. Its value is optional for the first BComponent Route to match (/B). The Route matches regardless of the parameter’s presence in the path.

參數(shù)化的第二種形式出現(xiàn)在routeMatrixParam(...) 。 請(qǐng)參見以下代碼行: this.router.navigate(['B', { parameter: value }]) 。 這種形式的parameter是矩陣參數(shù)。 對(duì)于第一個(gè)匹配的BComponent Route ( /B ),它的值是可選的。 該Route無論在路徑參數(shù)的存在相匹配。

The routeAddressParam(...) resolves a route that matches the http://localhost:4200/B/randomValue parameterization approach. This traditional strategy needs a parameter to match the second BComponent route (B/:parameter).

routeAddressParam(...)解析與http://localhost:4200/B/randomValue參數(shù)化方法匹配的路由。 這種傳統(tǒng)策略需要一個(gè)參數(shù)來匹配第二個(gè)BComponent路由( B/:parameter )。

The matrix strategy concerns routeMatrixParam(...). With or without a matrix parameter in its path, the first BComponent route still matches. The parameter parameter passes to BComponent just like with the traditional approach.

矩陣策略涉及routeMatrixParam(...) 。 路徑中有或沒有矩陣參數(shù),第一個(gè)BComponent路由仍然匹配。 parameter參數(shù)傳遞給BComponent就像傳統(tǒng)方法一樣。

To make full sense of the above code, here is the corresponding template HTML.

為了充分理解上述代碼,以下是相應(yīng)的模板HTML。

// app.component.html<ul><li routerLink="/A">Go to A!</li><li><input #matrixInput><button (click)="routeMatrixParam(matrixInput.value)">Matrix!</button></li><li><input #paramInput><button (click)="routeAddressParam(paramInput.value)">Param!</button></li> </ul> <router-outlet></router-outlet>

In the template, values are accepted as text input. The input injects it into the route path as a parameter. Two separate sets of boxes exist for each parameterization strategy (traditional and matrix). With all the pieces coming together, it is time to examine the BComponent component class.

在模板中,值被接受為文本輸入。 輸入將其作為參數(shù)注入到路徑中。 每個(gè)參數(shù)化策略(傳統(tǒng)方法和矩陣方法)都有兩組獨(dú)立的框。 將所有部分放在一起,是時(shí)候檢查BComponent組件類了。

// b.component.tsimport { Component, OnInit } from '@angular/core'; import { ActivatedRoute, ParamMap } from '@angular/router';@Component({selector: 'app-b',template: `<p>Route param: {{ currParam }}</p>` }) export class BComponent implements OnInit {currParam: string = "";constructor(private route: ActivatedRoute) { }ngOnInit() {this.route.params.subscribe((param: ParamMap) => {this.currParam = param['parameter'];});} }

BComponent results from either of two BComponent routes in AppRoutingModule. ActivatedRoute instantiates into a set of useful information pertaining to the current route. That is, the route that caused BComponent to render. ActivatedRoute instantiates via dependency injection targeting the class constructor.

BComponent來自AppRoutingModule中的兩個(gè)BComponent路由之一。 ActivatedRoute實(shí)例化為一組與當(dāng)前路由有關(guān)的有用信息。 也就是說,導(dǎo)致BComponent渲染的路由。 ActivatedRoute通過針對(duì)類構(gòu)造函數(shù)的依賴注入實(shí)例化。

The .params field of ActivatedRoute.params returns an Observable which emits the route parameters. Notice how the two different parameterization approaches result in the parameter parameter. The returned Observable emits it as a key-value pair inside of a ParamMap object.

ActivatedRoute.params的.params字段返回一個(gè)Observable ,它發(fā)出路由參數(shù)。 請(qǐng)注意,兩種不同的參數(shù)化方法是如何產(chǎn)生parameter參的。 返回的Observable其作為ParamMap對(duì)象內(nèi)部的鍵值對(duì)發(fā)出。

Between the two parameterization approaches, the parameter parameter resolved identically. The value emits from ActivatedRoute.params despite the approach to parameterization.

在兩種參數(shù)化方法之間, parameter參數(shù)解析相同。 盡管采用了參數(shù)化方法,但該值仍從ActivatedRoute.params發(fā)出。

The address bar distinguishes the final results of each approach. Matrix parameterization (optional for Route match) yields the address: http://localhost:4200/B;parameter=randomValue. Traditional parameterization (required for Route match) yields: http://localhost:4200/B/randomValue.

地址欄區(qū)分每種方法的最終結(jié)果。 矩陣參數(shù)化(對(duì)于Route match是可選的)產(chǎn)生地址: http://localhost:4200/B;parameter=randomValue 。 傳統(tǒng)的參數(shù)化(對(duì)于Route匹配是必需的)產(chǎn)生: http://localhost:4200/B/randomValue 。

Either way, the same BComponent results. The actual difference: a different BComponent Route matches. This entirely depends upon the parameterization strategy. The matrix approach ensures parameters are optional for Route matching. The traditional approach requires them.

無論哪種方式,都會(huì)得到相同的BComponent。 實(shí)際的區(qū)別:不同的BComponent Route匹配。 這完全取決于參數(shù)化策略。 矩陣方法確保參數(shù)對(duì)于Route匹配是可選的。 傳統(tǒng)方法需要它們。

嵌套路線 (Nested Routes)

Routes may form a hierarchy. In the DOM, this involves one parent router-outlet rendering at least one child router-outlet. In the address bar, it looks like this: http://localhost/parentRoutes/childRoutes. In the Routes configuration, the children: [] property denotes a Route object as having nested (child) routes.

Routes可以形成層次結(jié)構(gòu)。 在DOM中,這涉及一個(gè)父router-outlet至少渲染一個(gè)子router-outlet 。 在地址欄中,它看起來像這樣: http://localhost/parentRoutes/childRoutes 。 在Routes配置中, children: []屬性將Route對(duì)象表示為具有嵌套(子)路由。

import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router';import { NestComponent } from '../../components/nest/nest.component'; import { AComponent } from '../../components/nest/a/a.component'; import { BComponent } from '../../components/nest/b/b.component';const routes: Routes = [{path: 'nest',component: NestComponent,children: [{ path: 'A', component: AComponent },{ path: 'B', component: BComponent }]} ];@NgModule({imports: [ RouterModule.forRoot(routes) ],exports: [ RouterModule ] }) export class AppRoutingModule { }// nest.component.tsimport { Component } from '@angular/core';@Component({selector: 'app-nest',template: `<ul><li routerLink="./A">Go to A!</li><li routerLink="./B">Go to B!</li></ul><router-outlet></router-outlet>` }) export class NestComponent { }

NestComponent renders a router-outlet after rendering itself from another root-level router-outlet in AppComponent. The router-outlet of NestComponent’s template may render either AComponent (/nest/A) or BComponent (/nest/B).

NestComponent呈現(xiàn)一個(gè)router-outlet從另一個(gè)根級(jí)渲染本身后router-outlet在AppComponent。 NestComponent模板的router-outlet可以呈現(xiàn)AComponent( /nest/A )或BComponent( /nest/B )。

The AppRoutingModule reflects this nesting in NestComponent’s Route object. The children: [] field holds an array of Route objects. These Route object may also nest routes in their children: [] fields. This can continue for however many layers of nested routes. The above example shows two layers of nesting.

AppRoutingModule在NestComponent的Route對(duì)象中反映了此嵌套。 children: []字段包含Route對(duì)象的數(shù)組。 這些Route對(duì)象還可以將路由嵌套在其children: []字段中。 但是,對(duì)于多層嵌套路由,這可以繼續(xù)進(jìn)行。 上面的示例顯示了兩層嵌套。

Each routerLink contains a ./ as compared to /. The . ensures that the routerLink appends to the route path. The routerLink completely replaces the path otherwise. After routing to /nest, . expands into /nest.

與/相比,每個(gè)routerLink包含一個(gè)./ 。 的. 確保routerLink附加到路由路徑。 否則,routerLink會(huì)完全替換路徑。 路由到/nest , . 擴(kuò)展為/nest 。

This is useful for routing to either /nest/A or /nest/B from the .nest route. A and B constitute nested routes of /nest. Routing to /A or /B returns PageNotFound. /nest must prepend the two routes.

這對(duì)于從.nest路由到/nest/A或/nest/B .nest 。 A和B構(gòu)成/nest嵌套路由。 路由到/A或/B返回PageNotFound。 /nest必須在兩條路由之前。

Take a look at the AppComponent containing the root-level router-outlet in its template. AppComponent is the first layer of nesting while NestComponent is the second.

看一下在其模板中包含根級(jí)router-outlet的AppComponent。 AppComponent是嵌套的第一層,而NestComponent是第二層。

import { Component } from '@angular/core';@Component({selector: 'app-root',template: `<ul><li routerLink="/nest">Go to nested routes!</li><li routerLink="/">Back out of the nested routes!</li></ul><router-outlet></router-outlet>` }) export class AppComponent { }

Inside the nest Route object, the children: [] contains two more nested routes. They result in AComponent and BComponent when routing from /nest as previously discussed. These components are very simple for the sake of demonstration. <li routerLink="/">...</li> lets you navigate out of the nest routes to reset the example by navigating to the home route.

在嵌套R(shí)oute對(duì)象內(nèi)部, children: []包含另外兩個(gè)嵌套路由。 如前所述,從/nest路由時(shí),它們將導(dǎo)致AComponent和BComponent。 為了演示,這些組件非常簡(jiǎn)單。 <li routerLink="/">...</li>可讓您從嵌套路由中導(dǎo)航出來,以導(dǎo)航至本地路由來重置示例。

import { Component } from '@angular/core';@Component({selector: 'app-a',template: `<p>a works!</p>` }) export class AComponent { }import { Component } from '@angular/core';@Component({selector: 'app-b',template: `<p>b works!</p>` }) export class BComponent { }

The children: [] array accepts Route object as elements. children: [] can apply to any of these elements as well. The children of these elements can continue nesting. This pattern may continue for however many layers of nesting. Insert a router-outlet into the template for every layer of nested routing.

children: []數(shù)組接受Route對(duì)象作為元素。 children: []也可以應(yīng)用于這些元素中的任何一個(gè)。 這些元素的子級(jí)可以繼續(xù)嵌套。 無論多層嵌套如何,這種模式都可以繼續(xù)。 將嵌套路由的每一層的路由router-outlet插入模板。

Routing techniques apply regardless of a Route object’s level of nesting. The parameterization techniques differ in only one aspect. Child routes can only access their parent’s parameters via ActivatedRoute.parent.params. ActivatedRoute.params targets the same level of nested routes. This excludes parent-level routes and their parameters.

無論Route對(duì)象的嵌套級(jí)別如何,都適用路由技術(shù)。 參數(shù)化技術(shù)僅在一方面不同。 子路由只能通過ActivatedRoute.parent.params訪問其父級(jí)的參數(shù)。 ActivatedRoute.params目標(biāo)是相同級(jí)別的嵌套路由。 這不包括父級(jí)路由及其參數(shù)。

Route guards are especially suited for nested routing. One Route object can restrict access to all its nested (child) routes.

Route防護(hù)器特別適合嵌套路由。 一個(gè)Route對(duì)象可以限制對(duì)其所有嵌套(子)路由的訪問。

守衛(wèi)路線 (Guarded Routes)

Web applications often consist of public and private data. Both types of data tend to have their own pages with guarded routes. These routes allow/restrict access depending on the user’s privileges. Unauthorized users may interact with a guarded route. The route should block the user if he or she attempts to access its routed content.

Web應(yīng)用程序通常包含公共和私有數(shù)據(jù)。 兩種類型的數(shù)據(jù)都有自己的帶有受保護(hù)路由的頁面。 這些路由允許/限制訪問,具體取決于用戶的權(quán)限。 未經(jīng)授權(quán)的用戶可以與受保護(hù)的路由進(jìn)行交互。 如果用戶嘗試訪問其路由內(nèi)容,則該路由應(yīng)阻止用戶。

Angular provides a bundle of authentication guards that can attach to any route. These methods trigger automatically depending on how the user interacts with the guarded route.

Angular提供了可以連接到任何路由的身份驗(yàn)證防護(hù)包。 這些方法將根據(jù)用戶與受保護(hù)路線的交互方式自動(dòng)觸發(fā)。

  • canActivate(...) - fires when the user attempts to access a route

    canActivate(...) -用戶嘗試訪問路線時(shí)觸發(fā)

  • canActivateChild(...) - fires when the user attempts to access a route’s nested (child) routes

    canActivateChild(...) -當(dāng)用戶嘗試訪問路由的嵌套(子)路由時(shí)觸發(fā)

  • canDeactivate(...) - fires when the user attempts to leave a route

    canDeactivate(...) -用戶嘗試離開路線時(shí)觸發(fā)

Angular’s guard methods are available from @angular/router. To help them authenticate, they may optionally receive a few parameters. Such parameters do not inject via dependency injection. Under the hood, each value gets passed in as an argument to the invoked guard method.

可以從@angular/router獲得Angular的保護(hù)方法。 為了幫助他們進(jìn)行身份驗(yàn)證,他們可以選擇接收一些參數(shù)。 此類參數(shù)不會(huì)通過依賴項(xiàng)注入來注入。 在幕后,每個(gè)值都作為參數(shù)傳遞給調(diào)用的guard方法。

  • ActivatedRouteSnapshot - available to all three

    ActivatedRouteSnapshot全部三個(gè)都可用

  • RouterStateSnapshot - available to all three

    RouterStateSnapshot適用于所有三個(gè)

  • Component - available to canDeactivate(...)

    Component -可用于canDeactivate(...)

ActivatedRouteSnapshot provides access to the route parameters of the guarded route. RouterStateSnapshot exposes the URL (uniform resource locator) web address matching the route. Component references the component rendered by the route.

ActivatedRouteSnapshot提供對(duì)受保護(hù)路由的路由參數(shù)的訪問。 RouterStateSnapshot公開與路由匹配的URL(統(tǒng)一資源定位符)網(wǎng)址。 Component引用路線所呈現(xiàn)的組件。

To guard a route, a class implementing the guard methods needs to first exist as a service. The service can inject into AppRoutingModule to guard its Routes. The token value for the service may inject into any one Route object.

要保護(hù)路由,必須首先將實(shí)現(xiàn)保護(hù)方法的類作為服務(wù)存在。 該服務(wù)可以注入AppRoutingModule中以保護(hù)其Routes 。 服務(wù)的令牌值可以注入到任何一個(gè)Route對(duì)象中。

import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router';import { AuthService } from '../../services/auth.service'; import { UserService } from '../../services/user.service';import { PrivateNestComponent } from '../../components/private-nest/private-nest.component'; import { PrivateAComponent } from '../../components/private-nest/private-a/private-a.component'; import { PrivateBComponent } from '../../components/private-nest/private-b/private-b.component';const routes: Routes = [{path: 'private-nest',component: PrivateNestComponent,canActivate: [ AuthService ], // !!!canActivateChild: [ AuthService ], // !!!canDeactivate: [ AuthService ], // !!!children: [{ path: 'private-A', component: PrivateAComponent },{ path: 'private-B', component: PrivateBComponent }]} ];@NgModule({imports: [ RouterModule.forRoot(routes) ],exports: [ RouterModule ],providers: [AuthService,UserService] }) export class AppRoutingModule { }

canActivate, canActivateChild, and canDeactivate implement from AuthService. The service implementation will be shown shortly alongside the UserService implementation.

canActivate , canActivateChild和canDeactivate實(shí)現(xiàn)。 該服務(wù)實(shí)現(xiàn)將與UserService實(shí)現(xiàn)一起顯示。

UserService provides the information needed to authenticate a user. The AuthService guard method implementations perform the authentication. AppRoutingModule must include the two services into its providers array. This is so the module’s injector knows how to instantiate them.

UserService提供驗(yàn)證用戶所需的信息。 AuthService保護(hù)方法實(shí)現(xiàn)執(zhí)行身份驗(yàn)證。 AppRoutingModule must include the two services into its providers array. This is so the module's injector knows how to instantiate them.

Nested routes exist off of the /private-nest path. The Route object for /private-nest contains a few more new fields. Their names should look familiar as they mirror their corresponding guard methods.

Nested routes exist off of the /private-nest path. The Route object for /private-nest contains a few more new fields. Their names should look familiar as they mirror their corresponding guard methods.

Each field fires its namesake’s method implementation inside of the service when triggered. Any number of services can populate this array too. The method implementation of each service gets tested. They must return a boolean value or an Observable that emits a boolean value.

Each field fires its namesake's method implementation inside of the service when triggered. Any number of services can populate this array too. The method implementation of each service gets tested. They must return a boolean value or an Observable that emits a boolean value.

See the AuthService and UserService implementations below.

See the AuthService and UserService implementations below.

// user.service.tsimport { Injectable } from '@angular/core'; import { Router } from '@angular/router';class TheUser {constructor(public isLoggedIn: boolean = false) { }toggleLogin() {this.isLoggedIn = true;}toggleLogout() {this.isLoggedIn = false;} }const globalUser = new TheUser();@Injectable({providedIn: 'root' }) export class UserService {theUser: TheUser = globalUser;constructor(private router: Router) { }get isLoggedIn() {return this.theUser.isLoggedIn;}login() {this.theUser.toggleLogin();}logout() {this.theUser.toggleLogout();this.router.navigate(['/']);} }

The same instance of TheUser gets passed with each instantiation of UserService. TheUser provides access to isLoggedIn determining the user’s login status. Two other public methods let the UserService toggle the value of isLoggedIn. This is so the user can log in and out.

The same instance of TheUser gets passed with each instantiation of UserService. TheUser provides access to isLoggedIn determining the user's login status. Two other public methods let the UserService toggle the value of isLoggedIn . This is so the user can log in and out.

You can think of TheUser as a global instance. UserService is a instantiable interface that configures this global. Changes to TheUser from one UserService instantiation apply to every other UserService instance. UserService implements into AuthService to provide access to isLoggedIn of TheUser for authentication.

You can think of TheUser as a global instance. UserService is a instantiable interface that configures this global. Changes to TheUser from one UserService instantiation apply to every other UserService instance. UserService implements into AuthService to provide access to isLoggedIn of TheUser for authentication.

import { Component, Injectable } from '@angular/core'; import { CanActivate, CanActivateChild, CanDeactivate, ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';import { UserService } from './user.service';@Injectable({providedIn: 'root' }) export class AuthService implements CanActivate, CanActivateChild, CanDeactivate<Component> {constructor(private user: UserService) {}canActivate(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {if (this.user.isLoggedIn)return true;elsereturn false;}canActivateChild(route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {return this.canActivate(route, state);}canDeactivate(component: Component, route: ActivatedRouteSnapshot, state: RouterStateSnapshot) {if (!this.user.isLoggedIn || window.confirm('Leave the nest?'))return true;elsereturn false;} }

AuthService implements every guard method imported from @angular/router. Each guard method maps to a corresponding field in the PrivateNestComponent’s Route object. An instance of UserService instantiates from the AuthService constructor. AuthService determines if a user may proceed using isLoggedIn exposed by UserService.

AuthService implements every guard method imported from @angular/router . Each guard method maps to a corresponding field in the PrivateNestComponent's Route object. An instance of UserService instantiates from the AuthService constructor. AuthService determines if a user may proceed using isLoggedIn exposed by UserService.

Returning false from a guard instructs the route to block the user from routing. A return value of true lets the user proceed to his route destination. If more than one service authenticates, they all must return true to permit access. canActivateChild guards the child routes of PrivateNestComponent. This guard method accounts for users bypassing PrivateNestComponent through the address bar.

Returning false from a guard instructs the route to block the user from routing. A return value of true lets the user proceed to his route destination. If more than one service authenticates, they all must return true to permit access. canActivateChild guards the child routes of PrivateNestComponent. This guard method accounts for users bypassing PrivateNestComponent through the address bar.

Guard method parameters pass in automatically upon invocation. While the example does not make use of them, they do supply useful information from the route. The developer can use this information to help authenticate the user.

Guard method parameters pass in automatically upon invocation. While the example does not make use of them, they do supply useful information from the route. The developer can use this information to help authenticate the user.

AppComponent also instantiates UserService for direct use in its template. The UserService instantiation of AppComponent and AuthService reference the same user class (TheUser).

AppComponent also instantiates UserService for direct use in its template. The UserService instantiation of AppComponent and AuthService reference the same user class ( TheUser ).

import { Component } from '@angular/core';import { UserService } from './services/user.service';@Component({selector: 'app-root',template: `<ul><li routerLink="/private-nest">Enter the secret nest!</li><li routerLink="/">Leave the secret nest!</li><li *ngIf="user.isLoggedIn"><button (click)="user.logout()">LOGOUT</button></li><li *ngIf="!user.isLoggedIn"><button (click)="user.login()">LOGIN</button></li></ul><router-outlet></router-outlet>` }) export class AppComponent {constructor(private user: UserService) { } }

UserService handles all the logic for AppComponent. AppComponent mostly concerns its template. A UserService does instantiate as user from the class constructor. user data determines the template’s functionality.

UserService handles all the logic for AppComponent. AppComponent mostly concerns its template. A UserService does instantiate as user from the class constructor. user data determines the template's functionality.

結(jié)論 (Conclusions)

Routing strikes a fine balance between organizing and restricting sections of the application. A smaller application such as a blog or tribute page may not require any routing. Even then, including a little bit of hash routing could not hurt. A user may only want to reference part of the page after all.

Routing strikes a fine balance between organizing and restricting sections of the application. A smaller application such as a blog or tribute page may not require any routing. Even then, including a little bit of hash routing could not hurt. A user may only want to reference part of the page after all.

Angular applies its own routing library built on top of the HTML5 history API. This API omits hash routing to instead use the pushState(...) and replaceState(...) methods. They change the web address URL without refreshing the page. The default path location routing strategy in Angular works this way. Setting RouterModule.forRoot(routes, { useHash: true }) enables hash routing if preferred.

Angular applies its own routing library built on top of the HTML5 history API . This API omits hash routing to instead use the pushState(...) and replaceState(...) methods. They change the web address URL without refreshing the page. The default path location routing strategy in Angular works this way. Setting RouterModule.forRoot(routes, { useHash: true }) enables hash routing if preferred.

This article focused on the default path location strategy. Regardless of the strategy, many routing utilities are available to route an application. The RouterModule exposes these utilities through its exports. Basic, parameterized, nested, and guarded routes are all possible utilizing RouterModule.

This article focused on the default path location strategy. Regardless of the strategy, many routing utilities are available to route an application. The RouterModule exposes these utilities through its exports. Basic, parameterized, nested, and guarded routes are all possible utilizing RouterModule.

NgModules (NgModules)

Angular applications begin from the root NgModule. Angular manages an application’s dependencies through its module system comprised of NgModules. Alongside plain JavaScript modules, NgModules ensure code modularity and encapsulation.

Angular applications begin from the root NgModule. Angular manages an application's dependencies through its module system comprised of NgModules. Alongside plain JavaScript modules, NgModules ensure code modularity and encapsulation.

Modules also provide a top-most level of organizing code. Each NgModule sections off its own chunk of code as the root. This module provides top-to-bottom encapsulation for its code. The entire block of code can then export to any other module. In this sense, NgModules act like gatekeepers to their own code blocks.

Modules also provide a top-most level of organizing code. Each NgModule sections off its own chunk of code as the root. This module provides top-to-bottom encapsulation for its code. The entire block of code can then export to any other module. In this sense, NgModules act like gatekeepers to their own code blocks.

Angular’s documented utilities come from NgModules authored by Angular. No utility is available unless the NgModule that declares it gets included into the root. These utilities must also export from their host module so that importers can use them. This form of encapsulation empowers the developer to produce his or her own NgModules within the same file-system.

Angular's documented utilities come from NgModules authored by Angular. No utility is available unless the NgModule that declares it gets included into the root. These utilities must also export from their host module so that importers can use them. This form of encapsulation empowers the developer to produce his or her own NgModules within the same file-system.

Plus, it makes sense to know why the Angular CLI (command-line interface) imports BrowserModule from @angular/core. This happens whenever a new app generates using the CLI command: ng new [name-of-app].

Plus, it makes sense to know why the Angular CLI (command-line interface) imports BrowserModule from @angular/core . This happens whenever a new app generates using the CLI command: ng new [name-of-app] .

Understanding the point of the implementation may suffice in most cases. However, understanding how the implementation wires itself to the root is even better. It all happens automatically by importing BrowserModule into the root.

Understanding the point of the implementation may suffice in most cases. However, understanding how the implementation wires itself to the root is even better. It all happens automatically by importing BrowserModule into the root.

NgModule Decorator (NgModule Decorator)

Angular defines its modules by decorating a generic class. The @NgModule decorator indicates the class’ modular purpose to Angular. An NgModule class consolidates root dependencies accessible/instantiable from the module’s scope. ‘Scope’ meaning anything originating from the module’s metadata.

Angular defines its modules by decorating a generic class. The @NgModule decorator indicates the class' modular purpose to Angular. An NgModule class consolidates root dependencies accessible/instantiable from the module's scope. 'Scope' meaning anything originating from the module's metadata.

import { NgModule } from '@angular/core';@NgModule({// … metadata … }) export class AppModule { }

NgModule Metadata (NgModule Metadata)

The CLI generated root NgModule includes the following metadata fields. These fields provide configuration to the code block upon which the NgModule presides.

The CLI generated root NgModule includes the following metadata fields. These fields provide configuration to the code block upon which the NgModule presides.

  • declarations: []

    declarations: []

  • imports: []

    imports: []

  • providers: []

    providers: []

  • bootstrap: []

    bootstrap: []

聲明書 (Declarations)

The declarations array includes all components, directives, or pipes hosted by an NgModule. They are private to the module unless explicitly exported inside its metadata. Given this use-case, components, directives, and pipes are nicknamed ‘declarables’. An NgModule must declare a declarable uniquely. The declarable cannot declare twice in separate NgModules. An error gets thrown otherwise. See the below example.

The declarations array includes all components, directives, or pipes hosted by an NgModule. They are private to the module unless explicitly exported inside its metadata. Given this use-case, components, directives, and pipes are nicknamed 'declarables'. An NgModule must declare a declarable uniquely. The declarable cannot declare twice in separate NgModules. An error gets thrown otherwise. See the below example.

import { NgModule } from '@angular/core'; import { TwoComponent } from './components/two.component.ts';@NgModule({declarations: [ TwoComponent ] }) export class TwoModule { }@NgModule({imports: [ TwoModule ],declarations: [ TwoComponent ] }) export class OneModule { }

Angular throws an error for the sake of NgModule encapsulation. Declarables are private to the NgModule that declares them by default. If multiple NgModules need a certain declarable, they should import the declaring NgModule. This NgModule must then export the desired declarable so that the other NgModules can use it.

Angular throws an error for the sake of NgModule encapsulation. Declarables are private to the NgModule that declares them by default. If multiple NgModules need a certain declarable, they should import the declaring NgModule. This NgModule must then export the desired declarable so that the other NgModules can use it.

import { NgModule } from '@angular/core'; import { TwoComponent } from './components/two.component.ts';@NgModule({declarations: [ TwoComponent ],exports: [ TwoComponent ] }) export class TwoModule { }@NgModule({imports: [ TwoModule ] // this module can now use TwoComponent }) export class OneModule { }

The above example will not throw an error. TwoComponent has been uniquely declared between the two NgModules. OneModule also has access to TwoComponent since it imports TwoModule. TwoModule in turn exports the TwoComponent for external use.

The above example will not throw an error. TwoComponent has been uniquely declared between the two NgModules. OneModule also has access to TwoComponent since it imports TwoModule. TwoModule in turn exports the TwoComponent for external use.

Imports (Imports)

The imports array only accepts NgModules. This array does not accept declarables, services, or anything else besides other NgModules. Importing a module provides access to what declarable the module publicizes.

The imports array only accepts NgModules. This array does not accept declarables, services, or anything else besides other NgModules. Importing a module provides access to what declarable the module publicizes.

This explains why importing BrowserModule provides access to its various utilities. Each declarable utility declared in BrowserModule exports from its metadata. Upon importing BrowserModule, those exported declarables become available to the importing NgModule. Services do not export at all since they lack the same encapsulation.

This explains why importing BrowserModule provides access to its various utilities. Each declarable utility declared in BrowserModule exports from its metadata. Upon importing BrowserModule , those exported declarables become available to the importing NgModule. Services do not export at all since they lack the same encapsulation.

提供者 (Providers)

The lack of service encapsulation might seem odd given the encapsulation of declarables. Remember that services go into the providers array separate from declarations or exports.

The lack of service encapsulation might seem odd given the encapsulation of declarables. Remember that services go into the providers array separate from declarations or exports.

When Angular compiles, it flattens the root NgModule and its imports into one module. Services group together in a single providers array hosted by the merged NgModule. Declarables maintain their encapsulation through a set of compile-time flags.

When Angular compiles, it flattens the root NgModule and its imports into one module. Services group together in a single providers array hosted by the merged NgModule. Declarables maintain their encapsulation through a set of compile-time flags.

If NgModule providers contain matching token values, the importing root module takes precedence. Past that, the last NgModule imported takes precedence. See the next example. Pay special attention to the NgModule importing the other two. Recognize how that affects the precedence of the provided service.

If NgModule providers contain matching token values, the importing root module takes precedence. Past that, the last NgModule imported takes precedence. See the next example. Pay special attention to the NgModule importing the other two. Recognize how that affects the precedence of the provided service.

import { NgModule } from '@angular/core';@NgModule({providers: [ AwesomeService ], // 1st precedence + importing moduleimports: [BModule,CModule] }) export class AModule { }@NgModule({providers: [ AwesomeService ] // 3rd precedence + first import }) export class BModule { }@NgModule({providers: [ AwesomeService ] // 2nd precedence + last import }) export class CModule { }

Instantiating AwesomeService from within AModule’s scope results in an AwesomeService instance as provided in AModule’s metadata. If AModule’s providers omitted this service, the AwesomeService of CModule would take precedence. So and so forth for BModule if CModule’s providers omitted AwesomeService.

Instantiating AwesomeService from within AModule's scope results in an AwesomeService instance as provided in AModule's metadata. If AModule's providers omitted this service, the AwesomeService of CModule would take precedence. So and so forth for BModule if CModule's providers omitted AwesomeService.

引導(dǎo)程序 (Bootstrap)

The bootstrap array accepts components. For each component of the Array, Angular inserts the component as its own root of the index.html file. The CLI-generated root NgModule of an application will always have this field.

The bootstrap array accepts components. For each component of the Array, Angular inserts the component as its own root of the index.html file. The CLI-generated root NgModule of an application will always have this field.

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

AppComponent’s element will inject into the base-level HTML of the app (index.html). The rest of the component tree unfolds from there. The scope of the overarching NgModule covers this entire tree plus any others injected from the bootstrap array. The array usually contains only one element. This one component represents the module as a single element and its underlying tree.

AppComponent's element will inject into the base-level HTML of the app ( index.html ). The rest of the component tree unfolds from there. The scope of the overarching NgModule covers this entire tree plus any others injected from the bootstrap array. The array usually contains only one element. This one component represents the module as a single element and its underlying tree.

NgModules vs JavaScript Modules (NgModules vs JavaScript Modules)

You have seen Angular and JavaScript modules working together in the previous examples. The top-most import..from statements constitute the JavaScript module system. The file locations of each statement’s target must export a class, variable, or function matching the request. import { TARGET } from './path/to/exported/target'.

You have seen Angular and JavaScript modules working together in the previous examples. The top-most import..from statements constitute the JavaScript module system. The file locations of each statement's target must export a class, variable, or function matching the request. import { TARGET } from './path/to/exported/target' .

In JavaScript, modules are file-separated. Files import using the import..from keywords as just mentioned. NgModules, on the other hand, are class-separated and decorated with @NgModule. And so, many Angular modules can exist in a single file. This cannot happen with JavaScript since a file defines a module.

In JavaScript, modules are file-separated. Files import using the import..from keywords as just mentioned. NgModules, on the other hand, are class-separated and decorated with @NgModule . And so, many Angular modules can exist in a single file. This cannot happen with JavaScript since a file defines a module.

Granted, conventions say that each @NgModule decorated class should have its own file. Even so, know that files do not constitute their own modules in Angular. Classes decorated with @NgModule create that distinction.

Granted, conventions say that each @NgModule decorated class should have its own file. Even so, know that files do not constitute their own modules in Angular. Classes decorated with @NgModule create that distinction.

JavaScript modules provide token references to @NgModule metadata. This happens at the top of a file hosting a NgModule class. NgModule uses these tokens inside of its metadata fields (declarables, imports, providers, etc). The only reason @NgModule can decorate a class in the first place is because JavaScript imports it from the top of the file.

JavaScript modules provide token references to @NgModule metadata. This happens at the top of a file hosting a NgModule class. NgModule uses these tokens inside of its metadata fields (declarables, imports, providers, etc). The only reason @NgModule can decorate a class in the first place is because JavaScript imports it from the top of the file.

// JavaScript module system provides tokens import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component'; import { AppService } from './app.service'; // Javascript module system is strict about where it imports. It can only import at the top of files.// Angular NgModule uses those tokens in its metadata settings @NgModule({ // import { NgModule } from '@angular/core';declarations: [AppComponent // import { AppComponent } from './app.component';],imports: [BrowserModule // import { BrowserModule } from '@angular/platform-browser';],providers: [AppService // import { AppService } from './app.service';],bootstrap: [AppComponent // import { AppComponent } from './app.component';] }) export class AppModule { } // JavaScript module system exports the class. Other modules can now import AppModule.

The above example does not introduce anything new. The focus here is on the comments explaining how the two modular systems work together. JavaScript provides token references while NgModule uses those token to encapsulate and configure its underlying block of code.

The above example does not introduce anything new. The focus here is on the comments explaining how the two modular systems work together. JavaScript provides token references while NgModule uses those token to encapsulate and configure its underlying block of code.

Feature Modules (Feature Modules)

Applications grow overtime. Scaling them properly requires application organization. A solid system for this will make further development much easier.

Applications grow overtime. Scaling them properly requires application organization. A solid system for this will make further development much easier.

In Angular, schematics ensure purpose-driven sections of code remain distinguishable. Beyond the sub-NgModule schematics, there are the NgModules themselves. They are a type of schematic too. They stand above the rest in the list of schematics excluding the application itself.

In Angular, schematics ensure purpose-driven sections of code remain distinguishable. Beyond the sub-NgModule schematics, there are the NgModules themselves. They are a type of schematic too. They stand above the rest in the list of schematics excluding the application itself.

The root module should not stand alone once an application starts to scale. Feature modules include any NgModule used alongside the root NgModule. You can think of the root module as having the bootstrap: [] metadata field. Feature application ensure the root module does not oversaturate its metadata.

The root module should not stand alone once an application starts to scale. Feature modules include any NgModule used alongside the root NgModule. You can think of the root module as having the bootstrap: [] metadata field. Feature application ensure the root module does not oversaturate its metadata.

Feature modules isolate a section of code on behalf of any importing module. They can handle whole application sections independently. This means it could be used in any application whose root module imports the feature module. This tactic saves developers time and effort over the course of multiple applications! It keeps the application’s root NgModule lean as well.

Feature modules isolate a section of code on behalf of any importing module. They can handle whole application sections independently. This means it could be used in any application whose root module imports the feature module. This tactic saves developers time and effort over the course of multiple applications! It keeps the application's root NgModule lean as well.

In the root NgModule of an app, adding a feature module’s token into the root’s imports array does the trick. Whatever the feature module exports or provides becomes available to the root.

In the root NgModule of an app, adding a feature module's token into the root's imports array does the trick. Whatever the feature module exports or provides becomes available to the root.

// ./awesome.module.tsimport { NgModule } from '@angular/core'; import { AwesomePipe } from './awesome/pipes/awesome.pipe'; import { AwesomeComponent } from './awesome/components/awesome.component'; import { AwesomeDirective } from './awesome/directives/awesome.directive';@NgModule({exports: [AwesomePipe,AwesomeComponent,AwesomeDirective]declarations: [AwesomePipe,AwesomeComponent,AwesomeDirective] }) export class AwesomeModule { }// ./app.module.tsimport { AwesomeModule } from './awesome.module'; import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { AppComponent } from './app.component';@NgModule({declarations: [AppComponent],imports: [AwesomeModule,BrowserModule],providers: [],bootstrap: [AppComponent] }) export class AppModule { }// ./app.component.tsimport { Component } from '@angular/core';@Component({selector: 'app-root',template: `<!-- AwesomeDirective --><h1 appAwesome>This element mutates as per the directive logic of appAwesome.</h1><!-- AwesomePipe --><p>Generic output: {{ componentData | awesome }}</p><section><!-- AwesomeComponent --><app-awesome></app-awesome></section>` }) export class AppComponent {componentData: string = "Lots of transformable data!"; }

<app-awesome></app-awesome> (component), awesome (pipe), and appAwesome (directive) are exclusive to AwesomeModule. Had it not exported these declarables or AppModule neglected to add AwesomeModule to its imports, then AwesomeModule’s declarables would not have been usable by AppComponent’s template. AwesomeModule is a feature module to the root NgModule AppModule.

<app-awesome></app-awesome> (component), awesome (pipe), and appAwesome (directive) are exclusive to AwesomeModule. Had it not exported these declarables or AppModule neglected to add AwesomeModule to its imports, then AwesomeModule's declarables would not have been usable by AppComponent's template. AwesomeModule is a feature module to the root NgModule AppModule.

Angular provides some its own modules that supplement the root upon their importation. This is due to these feature modules exporting what they create.

Angular provides some its own modules that supplement the root upon their importation. This is due to these feature modules exporting what they create.

Static module methods (Static module methods)

Sometimes modules provide the option to be configured with a custom config object. This is achieved by leveraging static methods inside the module class.

Sometimes modules provide the option to be configured with a custom config object. This is achieved by leveraging static methods inside the module class.

An example of this approach is the RoutingModule which provides a .forRoot(...) method directly on the module.

An example of this approach is the RoutingModule which provides a .forRoot(...) method directly on the module.

To define your own static module method you add it to the module class using the static keyword. The return type has to be ModuleWithProviders.

To define your own static module method you add it to the module class using the static keyword. The return type has to be ModuleWithProviders .

// configureable.module.tsimport { AwesomeModule } from './awesome.module'; import { ConfigureableService, CUSTOM_CONFIG_TOKEN, Config } from './configurable.service'; import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core';@NgModule({imports: [AwesomeModule,BrowserModule],providers: [ConfigureableService] }) export class ConfigureableModule { static forRoot(config: Config): ModuleWithProviders {return {ngModule: ConfigureableModule,providers: [ConfigureableService,{provide: CUSTOM_CONFIG_TOKEN,useValue: config}]};} }// configureable.service.tsimport { Inject, Injectable, InjectionToken } from '@angular/core';export const CUSTOM_CONFIG_TOKEN: InjectionToken<string> = new InjectionToken('customConfig');export interface Config {url: string }@Injectable() export class ConfigureableService {constructor(@Inject(CUSTOM_CONFIG_TOKEN) private config: Config) }

Notice that the object the forRoot(...) method returns is almost identical to the NgModule config.

Notice that the object the forRoot(...) method returns is almost identical to the NgModule config.

The forRoot(...) method accepts a custom config object that the user can provide when importing the module.

The forRoot(...) method accepts a custom config object that the user can provide when importing the module.

imports: [...ConfigureableModule.forRoot({ url: 'http://localhost' }),... ]

The config is then provided using a custom InjectionToken called CUSTOM_CONFIG_TOKEN and injected in the ConfigureableService. The ConfigureableModule should be imported only once using the forRoot(...) method. This provides the CUSTOM_CONFIG_TOKEN with the custom config. All other modules should import the ConfigureableModule without the forRoot(...) method.

The config is then provided using a custom InjectionToken called CUSTOM_CONFIG_TOKEN and injected in the ConfigureableService . The ConfigureableModule should be imported only once using the forRoot(...) method. This provides the CUSTOM_CONFIG_TOKEN with the custom config. All other modules should import the ConfigureableModule without the forRoot(...) method.

NgModule Examples from Angular (NgModule Examples from Angular)

Angular provides a variety of modules importable from @angular. Two of the most commonly imported modules are CommonModule and HttpClientModule.

Angular provides a variety of modules importable from @angular . Two of the most commonly imported modules are CommonModule and HttpClientModule .

CommonModule is actually a subset of BrowserModule. Both provide access to the *ngIf and *ngFor structural directives. BrowserModule includes a platform-specific installation for the web browser. CommonModule omits this installation. The BrowserModule should import into the root NgModule of a web application. CommonModule provides *ngIf and *ngFor to feature modules not requiring a platform installation.

CommonModule is actually a subset of BrowserModule . Both provide access to the *ngIf and *ngFor structural directives. BrowserModule includes a platform-specific installation for the web browser. CommonModule omits this installation. The BrowserModule should import into the root NgModule of a web application. CommonModule provides *ngIf and *ngFor to feature modules not requiring a platform installation.

HttpClientModule provides the HttpClient service. Remember that services go in the providers array of the @NgModule metadata. They are not declarable. During compilation, every NgModule gets consolidated into one single module. Services are not encapsulated unlike declarables. They are all instantiable through the root injector located alongside the merged NgModule.

HttpClientModule provides the HttpClient service. Remember that services go in the providers array of the @NgModule metadata. They are not declarable. During compilation, every NgModule gets consolidated into one single module. Services are not encapsulated unlike declarables. They are all instantiable through the root injector located alongside the merged NgModule.

Back to the point. Like any other service, HttpClient instantiates into a class through its constructor via dependency injection (DI). Using DI, the root injector injects an instance of HttpClient into the constructor. This service lets developers make HTTP requests with the service’s implementation.

Back to the point. Like any other service, HttpClient instantiates into a class through its constructor via dependency injection (DI). Using DI, the root injector injects an instance of HttpClient into the constructor. This service lets developers make HTTP requests with the service's implementation.

The HttpClient implementation includes into the HttpClientModule providers array. As long as the root NgModule imports HttpClientModule, HttpClient will instantiate from inside the root’s scope as expected.

The HttpClient implementation includes into the HttpClientModule providers array. As long as the root NgModule imports HttpClientModule , HttpClient will instantiate from inside the root's scope as expected.

結(jié)論 (Conclusion)

Chances are you may have already taken advantage of Angular’s NgModules. Angular makes it very easy to throw a module into the root NgModule’s imports array. Utilities are often exported from the imported module’s metadata. Hence why its utilities suddenly become available upon importation within the root NgModule.

Chances are you may have already taken advantage of Angular's NgModules. Angular makes it very easy to throw a module into the root NgModule's imports array. Utilities are often exported from the imported module's metadata. Hence why its utilities suddenly become available upon importation within the root NgModule.

NgModules work closely with plain JavaScript modules. One provides token while one uses them for configuration. Their teamwork results in a robust, modular system unique to the Angular framework. It provides a new layer of organization above all other schematics excluding the application.

NgModules work closely with plain JavaScript modules. One provides token while one uses them for configuration. Their teamwork results in a robust, modular system unique to the Angular framework. It provides a new layer of organization above all other schematics excluding the application.

Hopefully this article furthers your understanding of NgModules. Angular can leverage this system even further for some of the more exotic use-cases.

Hopefully this article furthers your understanding of NgModules. Angular can leverage this system even further for some of the more exotic use-cases.

翻譯自: https://www.freecodecamp.org/news/angular-vs-angularjs/

flask框架視圖和路由

總結(jié)

以上是生活随笔為你收集整理的flask框架视图和路由_角度视图,路由和NgModule的解释的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

欧美黑人性爽 | 国产午夜小视频 | 成人av资源在线 | 91女人18片女毛片60分钟 | 免费色视频在线 | 久久视精品 | 国产日韩精品一区二区在线观看播放 | 久久99精品国产99久久6尤 | 亚洲成人精品av | 亚洲精品国产成人 | 毛片网在线 | 亚洲精品国产视频 | 综合在线观看色 | 园产精品久久久久久久7电影 | 久久无码精品一区二区三区 | 国内精品视频免费 | 久久精品国产亚洲 | 日本精品久久久久中文字幕 | 香蕉影视 | 欧美精品一二三 | 99视频国产精品 | 精品国产伦一区二区三区观看说明 | 91资源在线播放 | 九九九在线观看视频 | 日本在线中文 | 国产精品自在线拍国产 | 人人精品 | 亚洲男男gaygay无套 | 国产中文字幕久久 | 国产高清在线 | 一区二区三区免费在线 | 久久精品亚洲一区二区三区观看模式 | 国产高清专区 | 特级黄录像视频 | 久久久伦理 | 国产高清 不卡 | 九九免费精品视频在线观看 | 日日日日| 国产色视频一区二区三区qq号 | 国产精品久久99综合免费观看尤物 | 精品国产成人在线影院 | 午夜精品久久久久久99热明星 | 欧美国产视频在线 | 爱情影院aqdy鲁丝片二区 | 国产精品精品 | 九色在线| 欧美成人手机版 | 伊人中文网| 国产专区视频在线观看 | 在线免费中文字幕 | 99久久精品网 | 久久国产精品影视 | 日本老少交 | 岛国精品一区二区 | 天天干天天拍天天操天天拍 | 亚洲人在线 | 亚洲激情国产精品 | 久久丁香网 | 日本爽妇网 | 国产精品入口传媒 | 日本最新一区二区三区 | 国产一区网址 | 国产人成看黄久久久久久久久 | 久久久网页 | 日韩精品在线视频免费观看 | 精品一区二区在线免费观看 | 婷婷爱五月天 | 久草影视在线 | 色播五月激情综合网 | 中文字幕亚洲欧美日韩2019 | 天天综合人人 | 看片的网址 | 国产一级片毛片 | 在线观看深夜福利 | 国产日韩精品一区二区在线观看播放 | 国产在线精 | 欧美一区二区在线 | 成人影音在线 | 国产一区自拍视频 | av网站在线免费观看 | 久久精品国产免费观看 | 欧美黑人巨大xxxxx | www.99热精品 | 国产香蕉97碰碰久久人人 | 一区二区三区影院 | 国产一级黄色片免费看 | 9992tv成人免费看片 | 日本精品久久久久中文字幕 | 亚洲成人av电影在线 | 最新免费中文字幕 | 99久久久| 97涩涩视频 | 人人爱人人舔 | 久久精品电影 | 久久理论电影网 | 成人小视频在线 | 亚洲视频六区 | 日韩成人邪恶影片 | 亚洲精品国产精品乱码不99热 | 国产精品久久99综合免费观看尤物 | 亚洲精选99| www.亚洲视频 | 久久99精品久久久久久三级 | 中文字幕在线一二 | 九九视频在线观看视频6 | 好看的国产精品视频 | .精品久久久麻豆国产精品 亚洲va欧美 | 国产黄色片一级三级 | 天天操天天舔天天爽 | 久久99热精品 | 香蕉视频久久 | 天天插夜夜操 | 成人免费视频观看 | 日韩中文字幕免费在线观看 | 亚洲黄色在线免费观看 | www色网站| 久久撸在线视频 | 超碰在线国产 | 日韩经典一区二区三区 | av在线一级 | 夜夜夜夜猛噜噜噜噜噜初音未来 | 天天色天天操天天爽 | 天堂在线成人 | 亚洲国产精品久久久久婷婷884 | 高清国产在线一区 | 国产成人久久精品一区二区三区 | 在线国产一区二区 | 中文不卡视频 | 国产精品大全 | 亚洲精品国产精品乱码在线观看 | 国产一级性生活视频 | 久久久久电影网站 | 天天操综合 | 国产精品视频在线观看 | 精品一区二区免费视频 | 天天躁天天狠天天透 | 91亚洲精品在线 | av日韩中文 | 成年人视频在线免费观看 | 日韩免| 久热免费在线 | 色成人亚洲网 | 欧美日韩一区二区在线 | 国产中文伊人 | 久久久久亚洲精品国产 | 亚洲视频综合 | 日本中文字幕在线免费观看 | 性色av免费看 | 曰本三级在线 | 欧美性猛片 | 精品一区二区综合 | 天堂网一区二区三区 | 精品美女视频 | 国产福利精品在线观看 | 国产中文字幕视频在线 | 麻豆一二| 亚洲天堂网站 | 在线中文字幕观看 | 国产在线色视频 | 国产精品123 | 91看片看淫黄大片 | 久久久久久中文字幕 | 亚洲婷婷网 | 中文字幕在线免费观看 | 97精品国产97久久久久久粉红 | 日韩高清av在线 | 日韩电影黄色 | 日韩久久久久久久久久久久 | 丁香色婷婷| 九九热只有这里有精品 | 国产免费中文字幕 | 国产高清免费观看 | www色com| 91完整版观看| 在线成人国产 | 狠狠色狠狠色 | 久久综合狠狠综合久久激情 | 亚洲激情一区二区三区 | 成人性生交视频 | 欧美激情h | 午夜精品一区二区三区在线观看 | 精品视频国产一区 | 国产精品一区免费观看 | 亚洲精品国偷拍自产在线观看蜜桃 | 午夜精品一区二区三区视频免费看 | 视频精品一区二区三区 | 国产亚洲精品久久 | 国产精品久久久久久久久大全 | 成全免费观看视频 | 我要色综合天天 | 久久看片网站 | 久久精品视频免费观看 | 免费在线中文字幕 | 2022国产精品视频 | 亚欧洲精品视频在线观看 | 中文免费观看 | 99草在线视频 | 亚欧洲精品视频在线观看 | 精品一区二区精品 | 国产免费黄色 | 欧美日韩一区二区免费在线观看 | 91传媒91久久久 | 成人在线免费小视频 | 日韩不卡高清视频 | 久久人人爽人人 | 天天天天天天天操 | 精品一区二三区 | av观看免费在线 | 五月天中文字幕 | 中文字幕av在线不卡 | 日韩精品在线播放 | 国产91丝袜在线播放动漫 | 久久免费播放视频 | 欧美专区日韩专区 | 国产乱老熟视频网88av | www.天天色.com| 伊人一级 | 色综合亚洲精品激情狠狠 | 日本xxxx.com | 一区二区三区免费在线观看 | 99久久精品国产一区二区三区 | 天天干人人干 | 瑞典xxxx性hd极品 | 欧美美女视频在线观看 | 国产专区视频 | 91av电影在线 | 久久国产精品99久久久久 | 亚洲国产av精品毛片鲁大师 | 国产精品美女久久 | 精品国产一区二区三区四 | 日本资源中文字幕在线 | av在线免费观看黄 | 91黄色在线视频 | 国产亚洲精品久久久久久无几年桃 | 亚洲3级 | 国产亚洲成人网 | 99国产在线观看 | 狠狠色丁香久久婷婷综合五月 | 国产一级二级三级在线观看 | 91在线网站| 特级西西www44高清大胆图片 | 婷婷网五月天 | 天天干 夜夜操 | 欧美色综合久久 | 日韩视频www | 99国内精品 | 免费av福利 | 久久艹艹 | 一级免费观看 | www日韩视频 | 99精品视频免费 | 天天透天天插 | 欧美日韩不卡在线视频 | 狠狠狠色丁香婷婷综合久久五月 | 久久免费视频网 | 夜夜夜夜夜夜操 | 正在播放五月婷婷狠狠干 | 午夜在线观看一区 | 中文区中文字幕免费看 | 午夜色站 | 操天天操 | 色狠狠干 | 91色亚洲| 一级欧美日韩 | 精品国产成人av在线免 | 成人在线视频免费 | 夜夜高潮夜夜爽国产伦精品 | 亚洲第一伊人 | 国产不卡在线视频 | 日本精品一区二区在线观看 | 国产精品亚洲人在线观看 | 91在线视频精品 | 亚洲91精品| 久久激情综合网 | 久久久久女人精品毛片九一 | 国产在线观看黄 | 久草国产在线观看 | www.日本色| 香蕉在线观看 | 久久乱码卡一卡2卡三卡四 五月婷婷久 | 中文字幕一区二区三区精华液 | 天天射天天干天天操 | 久久久久麻豆 | 色婷婷激情 | 丝袜制服天堂 | 久久精品站 | av线上看 | 国产成人性色生活片 | 国产资源 | 久久精品人 | 西西人体www444 | 91九色在线视频 | 美女精品久久 | 天天插狠狠插 | 成人污视频在线观看 | 国产精品资源 | 二区视频在线观看 | 成人免费av电影 | 久久精品成人 | 中文字幕一区二区三区在线视频 | 国产伦精品一区二区三区在线 | 色婷婷激情 | 中文乱幕日产无线码1区 | 99精品免费在线 | 久久国内精品视频 | 色天天综合久久久久综合片 | 97超碰人人网 | 91久久精品一区二区三区 | 午夜精品99久久免费 | 婷婷成人综合 | 天天干天天做天天操 | 婷婷丁香在线 | 国产精品网红直播 | 91色在线观看视频 | 99久久精品午夜一区二区小说 | 人人澡人人添人人爽一区二区 | 狠狠色伊人亚洲综合网站野外 | 92精品国产成人观看免费 | 黄色影院在线播放 | 久久99国产精品久久99 | 国产在线观看h | 国产精品久久久久久69 | 亚洲夜夜网 | 激情综合亚洲精品 | 九色精品 | 五月婷在线观看 | 在线免费视频a | 成人黄色免费在线观看 | www.五月天婷婷.com | 中文字幕在线色 | 久久久国产日韩 | 99视频精品视频高清免费 | 国产二区视频在线观看 | 久久激情电影 | av在线播放一区二区三区 | 色天天中文 | 这里只有精品视频在线观看 | 亚洲国产精品一区二区久久,亚洲午夜 | 亚洲精品国产精品乱码在线观看 | 91热这里只有精品 | 欧美一级视频在线观看 | 99视频在线精品国自产拍免费观看 | 精品视频在线播放 | 99热在线这里只有精品 | 欧美人体xx | 97色噜噜 | 27xxoo无遮挡动态视频 | 欧美综合干 | 美女国产在线 | 欧美日韩国产在线精品 | 国产午夜一区 | 亚洲六月丁香色婷婷综合久久 | 在线观看色网 | 日韩视频免费观看高清完整版在线 | 日韩电影中文字幕在线观看 | 日韩欧美一区二区三区在线观看 | 在线一区电影 | 久久婷亚洲五月一区天天躁 | 欧美精品免费在线观看 | 久久久久久久久久毛片 | 日韩精品视频免费看 | 色天天中文 | 国产视频不卡 | 成年人看片网站 | 国产在线中文字幕 | 一区二区丝袜 | 国产在线不卡精品 | 99热在线免费观看 | 99精品欧美一区二区三区 | 在线播放精品一区二区三区 | 99热最新网址 | 干亚洲少妇 | 精品视频久久久久久 | 中文视频在线 | 国产色在线观看 | 亚洲色图激情文学 | 91欧美视频网站 | 日韩欧美在线观看一区 | 天天拍天天色 | 高清av在线 | 国产成人久久精品77777 | 久久欧洲视频 | 日本特黄一级片 | 在线看欧美 | 色偷偷97| 91av电影| 黄色一级网 | 狠狠狠综合 | 免费a级毛片在线看 | 久久精品小视频 | 日韩精品视频在线观看免费 | 在线观看国产www | 久久精品—区二区三区 | 国产淫片免费看 | 欧美日韩精品在线观看视频 | 97夜夜澡人人双人人人喊 | 91在线小视频| 欧美精品乱码久久久久久按摩 | 日韩欧美不卡 | 国产精选在线观看 | 天天摸夜夜操 | 久久久久国产a免费观看rela | 四虎在线观看网址 | 九色精品 | 天天干 天天摸 天天操 | 久久艹欧美 | 国产精品久久久久四虎 | 久久男女视频 | 久草爱 | 日韩av免费一区二区 | 精品国产乱码久久久久久天美 | 精品一区二三区 | 亚洲国产手机在线 | www.天天干 | 天天翘av| 蜜臀av性久久久久蜜臀aⅴ涩爱 | 一区久久久 | 国产精品99久久久久人中文网介绍 | 日韩一区二区免费视频 | 啪啪资源 | 欧美视频xxx | 欧美国产一区二区 | 国产一级三级 | 国产亚洲精品久久久久久无几年桃 | 精品国产乱码久久久久久1区二区 | 国产高清视频网 | 视频国产在线观看18 | 天天爱天天射天天干天天 | 国产一区在线精品 | 国产精品久久久久aaaa | 五月婷婷中文网 | av大全在线 | 亚洲国产电影在线观看 | 婷婷激情五月 | 日日夜夜中文字幕 | 成片视频免费观看 | 99中文字幕在线观看 | 国产亚洲成av人片在线观看桃 | 亚洲成人一区 | 韩日在线一区 | 国产日韩精品一区二区在线观看播放 | 91精品视频在线播放 | 国产91亚洲精品 | 中文在线a天堂 | 天天色中文 | 特级免费毛片 | 91在线视频精品 | 视频成人| 香蕉久草在线 | 免费高清在线观看电视网站 | 亚洲黄色免费在线 | 国产精品自拍在线 | 久久久久免费精品 | 在线观看国产v片 | 久久国产精品成人免费浪潮 | 国产偷国产偷亚洲清高 | 夜夜夜夜操| 日韩精品免费在线 | 亚洲精品国产精品国自产 | 成人资源站 | 在线看欧美 | 中文国产成人精品久久一 | 九九热99视频 | 国产成人在线免费观看 | 国产激情小视频在线观看 | 欧美一区二区三区特黄 | 91女子私密保健养生少妇 | 亚洲网站在线看 | 国产一级免费电影 | 日韩激情网 | av在线永久免费观看 | 国产91精品一区二区麻豆网站 | 麻豆视传媒官网免费观看 | 插婷婷 | 久久久国产精品免费 | av成年人电影| 天天摸天天舔 | 中文字幕 第二区 | 天天爱综合 | 麻豆国产网站 | 中文字幕精品一区久久久久 | 国产中出在线观看 | 久久久免费观看完整版 | 日韩精品视频免费在线观看 | 国产高清不卡一区二区三区 | 日韩性色 | 国产高清在线视频 | 久久福利综合 | 久久久国产精品久久久 | 久久少妇av | 国产精品一区久久久久 | 亚洲小视频在线 | 国产亚洲综合性久久久影院 | 精品国产一区二区三区四 | 日本中文不卡 | 美女视频永久黄网站免费观看国产 | 国产h在线观看 | 超碰电影在线观看 | 欧美日韩在线观看不卡 | 国产福利91精品张津瑜 | 三级av片 | 日韩视频免费在线观看 | 香蕉免费在线 | 欧美一区二区伦理片 | 欧美成人黄色 | 天天综合成人网 | 精品高清视频 | 亚洲精品自在在线观看 | av不卡免费在线观看 | 日韩高清精品一区二区 | 色多多视频在线观看 | 国产在线精品视频 | 久久黄色免费 | 免费a视频 | 精品在线观看一区二区三区 | 日韩免费在线网站 | 久久久www免费电影网 | 超碰官网 | 日韩欧美精品一区二区三区经典 | 综合久久影院 | 免费看黄在线 | 欧美9999 | 亚洲国产一二三 | 韩国一区二区三区在线观看 | 久久精品视频中文字幕 | www.com黄色| 欧美午夜寂寞影院 | 国产中文a | 九九热在线视频免费观看 | 久久视频国产 | 国产精品v欧美精品v日韩 | 在线免费观看的av网站 | 日韩免费电影一区二区三区 | 最近中文字幕高清字幕免费mv | 久久视频在线观看免费 | 精品久久国产精品 | 91九色成人 | 免费的黄色的网站 | 天天色天天色天天色 | 天天色天天射天天操 | 久久国产精品一区二区三区四区 | 亚洲色图激情文学 | 国内精品久久天天躁人人爽 | 香蕉免费 | 亚洲精品国产高清 | 国产免费专区 | 香蕉精品视频在线观看 | 韩国三级一区 | 97在线观看免费观看 | 国产亚洲精品bv在线观看 | 免费看成人av | 在线免费观看国产 | 97av在线视频免费播放 | 亚洲精品456在线播放乱码 | av在线影视 | 免费下载高清毛片 | 国产福利在线免费观看 | 男女拍拍免费视频 | 日韩videos | 亚洲一区欧美激情 | 九九热精品国产 | 日韩精选在线 | 中文字幕中文字幕在线中文字幕三区 | 视频二区在线 | 香蕉视频18 | www色,com| 一区二区视 | aaaaaa毛片| 午夜精品久久久久久久99水蜜桃 | 美女视频黄免费 | 国产在线观看不卡 | 在线日本看片免费人成视久网 | 亚洲精品在线播放视频 | 激情综合网在线观看 | 婷婷丁香视频 | 亚洲精品18p | 国产一级免费在线观看 | 不卡国产视频 | 国产一级视频免费看 | 成人免费观看a | 亚洲精品中文在线观看 | 国内久久精品 | 亚洲综合一区二区精品导航 | 99爱精品在线 | www.香蕉 | 免费看污的网站 | 国产91在线看 | 欧美性做爰猛烈叫床潮 | 久久久久久久久久毛片 | 国产在线视频导航 | 久久综合成人 | 精品日韩在线 | 久久综合影音 | 成年人在线观看免费视频 | 免费视频97 | 视频二区在线视频 | www.伊人色.com | 日韩欧美一区二区不卡 | 国产精品一区欧美 | 欧美国产一区二区 | 九九视频在线观看视频6 | 日韩欧美区 | 亚洲精品免费在线观看 | wwwwww国产 | 成人h在线播放 | 亚洲精品视频在线观看视频 | 欧美日韩伦理在线 | 欧美激情第八页 | 人人精久 | 日韩av中文在线观看 | 中文字幕在线网 | 视频国产在线 | 91九色精品女同系列 | 国产99久久久精品 | 五月开心激情网 | 婷婷六月天丁香 | 亚洲网站在线看 | 国产亚洲亚洲 | 精品久久久久久久久久久久 | 日本性生活一级片 | 六月色 | 久久久国产视频 | 涩av在线 | 99久久er热在这里只有精品66 | 亚洲视频aaa | 超碰在线1 | 免费精品国产 | 亚洲1区 在线 | 国产一区二区午夜 | 免费a视频在线观看 | 成年人免费看片 | 欧美 日韩 视频 | 欧美成人在线免费观看 | 色伊人网 | 亚洲精品小区久久久久久 | 亚洲视频免费在线看 | 亚洲免费精彩视频 | 五月婷婷一区 | 不卡的av在线 | 九色91av| 夜夜躁狠狠躁日日躁视频黑人 | 免费a网 | 中文字幕精品一区久久久久 | 日本中文字幕高清 | 91大神dom调教在线观看 | 久久九九影视网 | 91色在线观看视频 | 亚洲成人影音 | 欧美另类xxx | 亚洲色图色 | 久久精品国产第一区二区三区 | 欧美一二三区在线观看 | 国产一区二区在线影院 | 欧美久久久久久久久久久久 | 午夜国产福利在线 | 97免费在线视频 | 成年人视频在线观看免费 | 亚洲精品乱码白浆高清久久久久久 | 天天亚洲| 欧美久久久久久久久中文字幕 | 精品久久一二三区 | 久久久久久久久久久久久久av | 超碰在线公开免费 | www.黄色网.com | 麻豆 91 在线| 国产美女精品久久久 | 欧美午夜剧场 | 欧美日韩成人一区 | 欧美电影在线观看 | 色婷婷综合在线 | 亚洲影视九九影院在线观看 | 亚洲精品播放 | 午夜精品中文字幕 | 欧洲精品亚洲精品 | 99国产精品久久久久老师 | 日韩中文在线视频 | 日韩av中文字幕在线免费观看 | 日韩精品免费一区二区在线观看 | 欧美地下肉体性派对 | 国产美女精品人人做人人爽 | 四川妇女搡bbbb搡bbbb搡 | 国产精品国产三级国产aⅴ入口 | 日日夜操 | 国产视频一区在线播放 | 国产精品欧美久久久久天天影视 | 国产精品午夜8888 | 免费视频在线观看网站 | 久久一区精品 | 亚洲自拍偷拍色图 | 久久精品亚洲精品国产欧美 | 天天曰夜夜爽 | 日日操日日 | 香蕉视频网站在线观看 | 日韩欧美专区 | 99久久精品午夜一区二区小说 | 人人干,人人爽 | 国产精品一区二区三区在线免费观看 | 五月婷婷六月综合 | 欧美日韩视频在线一区 | 国产精品1区2区 | 91亚州| 亚洲蜜桃av| 精品一区二区三区久久久 | 亚洲人久久 | 免费看的黄色网 | 日本中文乱码卡一卡二新区 | 日韩精品国产一区 | 亚洲成人av电影在线 | 久久伊人精品天天 | 亚洲国产三级在线观看 | 国产精品久久久精品 | 色妞色视频一区二区三区四区 | 亚洲精品国产综合99久久夜夜嗨 | 精品国产视频在线 | 久久久久日本精品一区二区三区 | 欧美日韩精品免费观看视频 | 五月婷婷综合在线视频 | 国产 精品 资源 | 日韩高清在线一区 | 99久久精品一区二区成人 | 成人毛片在线观看视频 | 亚洲免费在线观看视频 | 美女性爽视频国产免费app | 精品视频不卡 | 日韩一区二区免费在线观看 | 日韩欧美一区二区三区在线 | 久久这里精品视频 | 国产91在线观看 | 日韩电影在线观看一区 | 亚洲精品91天天久久人人 | 国产一区二区三区午夜 | 久久国产精品一区二区三区四区 | 99久久爱 | 中文字幕精品视频 | 久久永久免费 | 超碰成人免费电影 | 久久久久久久亚洲精品 | 日韩在线观看第一页 | 国产成人精品久久久久蜜臀 | 久久国产精品99久久人人澡 | 日本性视频 | 亚洲精品视频在线观看网站 | 亚洲特级毛片 | 99在线视频观看 | 91福利区一区二区三区 | 国产一级电影网 | 99久久爱 | 久久婷婷一区 | 中文字幕在线视频一区二区 | 在线国产日本 | 亚洲欧美日韩国产精品一区午夜 | 黄色三级免费网址 | 国产成人三级在线 | 日韩视频免费观看高清完整版在线 | 精品亚洲成人 | 四虎影视av | 日韩成人av在线 | 手机在线视频福利 | 2024av| 四虎在线视频免费观看 | 日精品在线观看 | 成人av免费在线 | av福利网址导航 | 免费在线观看黄网站 | 午夜av色 | 欧美亚洲精品一区 | 91高清一区 | 射九九| 懂色av一区二区三区蜜臀 | 综合色久 | 国产一级在线视频 | 免费成人在线视频网站 | 99久久免费看 | 狠狠色丁香婷婷 | 又色又爽又黄高潮的免费视频 | 亚洲三级视频 | av黄色在线观看 | 免费裸体视频网 | 99热在线这里只有精品 | 久免费视频 | 黄色毛片在线观看 | 黄网站免费大全入口 | 久久欧洲视频 | 婷婷五月在线视频 | 久久人人爽人人人人片 | 在线观看一级 | 亚洲色图色 | 免费看成年人 | 免费在线观看视频一区 | 国产一区视频导航 | 午夜黄色 | 中文字幕乱在线伦视频中文字幕乱码在线 | 精品国产99 | 4438全国亚洲精品在线观看视频 | 美女搞黄国产视频网站 | 天天干,天天操 | 欧美久久久久久久 | 国产中出在线观看 | 在线日韩av| 精品国产aⅴ一区二区三区 在线直播av | 69久久夜色精品国产69 | 五月婷婷天堂 | 久久99精品国产99久久 | 狠狠操导航 | av福利在线 | 久久xxxx| 国内精品在线观看视频 | 狠狠干成人 | 欧美日韩中文字幕在线视频 | 91在线永久| 奇米四色影狠狠爱7777 | 亚洲电影免费 | 少妇搡bbbb搡bbb搡69 | 欧洲一区二区在线观看 | 93久久精品日日躁夜夜躁欧美 | 国产精品igao视频网入口 | 福利视频午夜 | 亚洲精品久久久久久久蜜桃 | 国产精品视频免费看 | 亚洲视频网站在线观看 | 亚洲欧美日韩国产一区二区三区 | 日韩精品一区二区三区第95 | 午夜精品一区二区三区在线 | 免费亚洲一区二区 | av日韩精品 | 精品字幕| 天天操天天吃 | 一级黄色电影网站 | 国产小视频你懂的 | 在线a人片免费观看视频 | 狠狠色丁香婷婷综合久小说久 | 久久久久久久久综合 | 激情婷婷丁香 | 国产一级电影 | 午夜精品一区二区三区在线视频 | 成人中文字幕+乱码+中文字幕 | 亚洲精品美女在线观看 | 中文理论片 | 成人黄色在线视频 | 久久精品影视 | 欧美 日韩 视频 | 美女网站视频免费黄 | 欧美国产91 | 亚洲国产精品激情在线观看 | 黄网站a| 99色在线观看视频 | 麻豆一级视频 | 欧美日韩高清一区二区 | 黄色大片日本免费大片 | 欧美精品v国产精品v日韩精品 | 91 | 怡春院av| 亚洲免费资源 | 99视频在线免费播放 | 四虎视频 | 91网在线看 | 久久久伦理 | 99热这里只有精品久久 | 午夜精品视频一区 | 亚洲精品在线一区二区三区 | 99久久爱| 五月天婷亚洲天综合网鲁鲁鲁 | 嫩小bbbb摸bbb摸bbb | 日韩免 | 欧美午夜一区二区福利视频 | 91在线视频播放 | 91大神精品视频在线观看 | 国产视频91在线 | 成年人网站免费在线观看 | 国产一区二区三区在线免费观看 | av在线永久免费观看 | 免费试看一区 | 黄色网www| 国产区欧美 | 国产一级免费观看 | 欧美日韩免费在线视频 | 国产在线播放一区二区三区 | 青草视频在线 | 一级片免费在线 | 国产精品成人av电影 | 亚洲一级理论片 | 999久久久免费视频 午夜国产在线观看 | 国产午夜在线 | 国产免费又爽又刺激在线观看 | 综合av在线| 久久成人精品电影 | 欧美一级小视频 | 黄色软件在线观看 | av国产在线观看 | 黄色三级在线 | 欧美国产91| 欧美与欧洲交xxxx免费观看 | 婷婷久久网 | 99久久99久久精品免费 | 九月婷婷色 | 色综合天天综合网国产成人网 | 成人动漫视频在线 | 久草色在线观看 | 色婷婷婷| 欧美日韩国产精品一区二区亚洲 | 久久毛片视频 | 国产无套一区二区三区久久 | 国产亚洲精品久久 | 久久精品国产亚洲aⅴ | 色婷婷色| 欧美在线观看视频一区二区 | 欧美日本中文字幕 | 久久伊人婷婷 | 性色视频在线 | 日韩在线观看影院 | 久久99精品久久久久久清纯直播 | 久久日本视频 | 国产精品国产三级国产aⅴ9色 | 色综合天天色综合 | 色小说在线 | 国产精品精品视频 | 97碰视频| 毛片播放网站 | 国产小视频在线免费观看视频 | 欧美日韩网站 | 97在线视频免费观看 | 黄污污网站 | 色94色欧美 | 亚洲涩涩网站 | 国产一区视频在线 | 丁香婷婷综合色啪 | 欧美日韩免费看 | 91麻豆视频网站 | www.亚洲黄色 | 国产无遮挡又黄又爽在线观看 | 中文字幕av全部资源www中文字幕在线观看 | 中文字幕黄色网 | 婷婷国产v亚洲v欧美久久 | 女人高潮特级毛片 | 91成年人在线观看 | 精品国产123 | 狠狠狠狠狠狠 | 亚洲性少妇性猛交wwww乱大交 | 国产一二三区在线观看 | 国产小视频在线观看免费 | 欧美精品在线一区二区 | 国产精品综合久久久久 | 天天操天天操天天 | 国产在线精品国自产拍影院 | 国产色综合天天综合网 | 欧美巨乳波霸 | 超碰97.com | 天天综合精品 | 波多野结衣久久资源 | 免费黄色网止 | 日韩中文字幕视频在线 | 日韩高清av在线 | 午夜精品久久久久久久久久久久久久 | 成人h视频 | 久久夜色精品国产亚洲aⅴ 91chinesexxx | 久久综合桃花 | 国产成人一级电影 | 欧美精品视 | 99在线高清视频在线播放 | 免费看成人av | 99久久久久成人国产免费 | 一本一道久久a久久综合蜜桃 | 久久毛片视频 | 人人藻人人澡人人爽 | 日韩精品一区二区免费视频 | 丁香花在线视频观看免费 | 91亚洲国产 | 国产精品三级视频 | 久久99亚洲精品久久 | 婷婷播播网 | 精品国内自产拍在线观看视频 | 丝袜精品视频 | 欧美一区在线看 | 日韩视频免费 | 黄色字幕网 | 色哟哟国产精品 | 成人免费观看a | 久草在线视频网站 | 中文字幕在线视频精品 | 欧洲精品视频一区 | www.狠狠 | 特级毛片网 | 视频在线91 | 一区二区三区在线观看中文字幕 | 免费韩国av | www.夜夜操.com | 国产成人一区二区三区免费看 | 九九免费精品 | 国产在线综合视频 | 国产99免费 | 91亚洲综合| 久久精品永久免费 | 精品久久福利 | 久久久久久久久毛片精品 | 久久久久电影网站 | 激情五月播播久久久精品 | 天天操夜操视频 | 日本精品视频网站 |