2018-05-15

根據(jù)名字搜索

https://angular.io/tutorial/toh-pt6#search-by-name

在最后一次練習中盆均,你要學到把 Observable 的操作符串在一起魏割,讓你能將相似 HTTP 請求的數(shù)量最小化橙依,并節(jié)省網(wǎng)絡帶寬。

你將往儀表盤中加入英雄搜索特性。 當用戶在搜索框中輸入名字時白嘁,你會不斷發(fā)送根據(jù)名字過濾英雄的 HTTP 請求。 你的目標是僅僅發(fā)出盡可能少的必要請求膘流。

HeroService.searchHeroes

先把 searchHeroes 方法添加到 HeroService 中权薯。

<code-example path="toh-pt6/src/app/hero.service.ts" region="searchHeroes" ng-version="5.2.0" style="clear: both; display: block; background-color: rgba(242, 242, 242, 0.2); border: 0.5px solid rgb(219, 219, 219); border-radius: 5px; color: rgb(51, 51, 51); margin: 16px auto; font-family: Roboto, "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><header class="ng-star-inserted" style="background-color: rgb(30, 136, 229); border-radius: 5px 5px 0px 0px; color: rgb(250, 250, 250); font-size: 16px; padding: 8px 16px;">src/app/hero.service.ts</header>

<aio-code class="headed-code"><pre class="prettyprint lang-" style="display: flex; min-height: 32px; margin: 16px 24px; white-space: pre-wrap; -webkit-box-align: center; align-items: center; position: relative;">content_copy /* GET heroes whose name contains search term */ searchHeroes(term: string): Observable<Hero[]> { if (!term.trim()) { // if not search term, return empty hero array. return of([]); } return this.http.get<Hero[]>(api/heroes/?name=${term}).pipe( tap(_ => this.log(found heroes matching "${term}")), catchError(this.handleError<Hero[]>('searchHeroes', [])) ); }</pre></aio-code></code-example>

如果沒有搜索詞,該方法立即返回一個空數(shù)組睡扬。 剩下的部分和 getHeroes() 很像。 唯一的不同點是 URL黍析,它包含了一個由搜索詞組成的查詢字符串卖怜。

為儀表盤添加搜索功能

打開 DashboardComponent模板并且把用于搜索英雄的元素 <app-hero-search> 添加到 DashboardComponent模板的底部。

<code-example path="toh-pt6/src/app/dashboard/dashboard.component.html" linenums="false" ng-version="5.2.0" style="clear: both; display: block; background-color: rgba(242, 242, 242, 0.2); border: 0.5px solid rgb(219, 219, 219); border-radius: 5px; color: rgb(51, 51, 51); margin: 16px auto; font-family: Roboto, "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><header class="ng-star-inserted" style="background-color: rgb(30, 136, 229); border-radius: 5px 5px 0px 0px; color: rgb(250, 250, 250); font-size: 16px; padding: 8px 16px;">src/app/dashboard/dashboard.component.html</header>

<aio-code class="headed-code"><pre class="prettyprint lang-" style="display: flex; min-height: 32px; margin: 16px 24px; white-space: pre-wrap; -webkit-box-align: center; align-items: center; position: relative;">content_copy <h3>Top Heroes</h3> <div class="grid grid-pad"> <[a](https://angular.cn/api/router/RouterLinkWithHref) *[ngFor](https://angular.cn/api/common/NgForOf)="let hero of heroes" class="col-1-4" [routerLink](https://angular.cn/api/router/RouterLink)="/detail/{{hero.id}}"> <div class="module hero"> <h4>{{hero.name}}</h4> </div> </[a](https://angular.cn/api/router/RouterLinkWithHref)> </div> <app-hero-search></app-hero-search></pre></aio-code></code-example>

這個模板看起來很像 HeroesComponent 模板中的 *[ngFor](https://angular.cn/api/common/NgForOf) 復寫器阐枣。

很不幸马靠,添加這個元素讓本應用掛了。 Angular 找不到哪個組件的選擇器能匹配上 <app-hero-search>蔼两。

HeroSearchComponent 還不存在甩鳄,這就解決。

創(chuàng)建 HeroSearchComponent

使用 CLI 創(chuàng)建一個 HeroSearchComponent额划。

<code-example language="sh" class="code-shell" ng-version="5.2.0" style="clear: both; display: block; background-color: rgb(51, 51, 51); border: 0.5px solid rgb(219, 219, 219); border-radius: 5px; color: rgb(51, 51, 51); margin: 16px auto; font-family: Roboto, "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><aio-code class="simple-code"><pre class="prettyprint lang-sh" style="display: flex; min-height: 32px; margin: 16px 24px; white-space: pre-wrap; -webkit-box-align: center; align-items: center; position: relative;">content_copy ng generate component hero-search</pre></aio-code></code-example>

CLI 生成了 HeroSearchComponent 的三個文件妙啃,并把該組件添加到了 AppModule 的聲明中。

把生成的 HeroSearchComponent模板改成一個輸入框和一個匹配到的搜索結(jié)果的列表。代碼如下:

<code-example path="toh-pt6/src/app/hero-search/hero-search.component.html" ng-version="5.2.0" style="clear: both; display: block; background-color: rgba(242, 242, 242, 0.2); border: 0.5px solid rgb(219, 219, 219); border-radius: 5px; color: rgb(51, 51, 51); margin: 16px auto; font-family: Roboto, "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><header class="ng-star-inserted" style="background-color: rgb(30, 136, 229); border-radius: 5px 5px 0px 0px; color: rgb(250, 250, 250); font-size: 16px; padding: 8px 16px;">src/app/hero-search/hero-search.component.html</header>

<aio-code class="headed-code"><pre class="prettyprint lang-" style="display: flex; min-height: 32px; margin: 16px 24px; white-space: pre-wrap; -webkit-box-align: center; align-items: center; position: relative;">content_copy <div id="search-component"> <h4>Hero Search</h4> <input #searchBox id="search-box" (keyup)="search(searchBox.value)" /> <ul class="search-result"> <li *[ngFor](https://angular.cn/api/common/NgForOf)="let hero of heroes$ | [async](https://angular.cn/api/core/testing/async)" > <[a](https://angular.cn/api/router/RouterLinkWithHref) [routerLink](https://angular.cn/api/router/RouterLink)="/detail/{{hero.id}}"> {{hero.name}} </[a](https://angular.cn/api/router/RouterLinkWithHref)> </li> </ul> </div></pre></aio-code></code-example>

從下面的 最終代碼 中把私有 CSS 樣式添加到 hero-search.component.css 中揖赴。

當用戶在搜索框中輸入時馆匿,一個 keyup 事件綁定會調(diào)用該組件的 search() 方法,并傳入新的搜索框的值燥滑。

AsyncPipe

如你所愿渐北,*[ngFor](https://angular.cn/api/common/NgForOf) 重復渲染出了這些英雄。

仔細看铭拧,你會發(fā)現(xiàn) *[ngFor](https://angular.cn/api/common/NgForOf) 是在一個名叫 heroes$ 的列表上迭代赃蛛,而不是 heroes

<code-example path="toh-pt6/src/app/hero-search/hero-search.component.html" region="async" ng-version="5.2.0" style="clear: both; display: block; background-color: rgba(242, 242, 242, 0.2); border: 0.5px solid rgb(219, 219, 219); border-radius: 5px; color: rgb(51, 51, 51); margin: 16px auto; font-family: Roboto, "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><aio-code class="simple-code"><pre class="prettyprint lang-" style="display: flex; min-height: 32px; margin: 16px 24px; white-space: pre-wrap; -webkit-box-align: center; align-items: center; position: relative;">content_copy <li *[ngFor](https://angular.cn/api/common/NgForOf)="let hero of heroes$ | [async](https://angular.cn/api/core/testing/async)" ></pre></aio-code></code-example>

$ 是一個命名慣例搀菩,用來表明 heroes$ 是一個 Observable呕臂,而不是數(shù)組。

*[ngFor](https://angular.cn/api/common/NgForOf) 不能直接使用 Observable秕磷。 不過诵闭,它后面還有一個管道字符(|),后面緊跟著一個 [async](https://angular.cn/api/core/testing/async)澎嚣,它表示 Angular 的 [AsyncPipe](https://angular.cn/api/common/AsyncPipe)疏尿。

[AsyncPipe](https://angular.cn/api/common/AsyncPipe) 會自動訂閱到 Observable,這樣你就不用再在組件類中訂閱了易桃。

修正 HeroSearchComponent

修改所生成的 HeroSearchComponent 類及其元數(shù)據(jù)褥琐,代碼如下:

<code-example path="toh-pt6/src/app/hero-search/hero-search.component.ts" ng-version="5.2.0" style="clear: both; display: block; background-color: rgba(242, 242, 242, 0.2); border: 0.5px solid rgb(219, 219, 219); border-radius: 5px; color: rgb(51, 51, 51); margin: 16px auto; font-family: Roboto, "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><header class="ng-star-inserted" style="background-color: rgb(30, 136, 229); border-radius: 5px 5px 0px 0px; color: rgb(250, 250, 250); font-size: 16px; padding: 8px 16px;">src/app/hero-search/hero-search.component.ts</header>

<aio-code class="headed-code"><pre class="prettyprint lang-" style="display: flex; min-height: 32px; margin: 16px 24px; white-space: pre-wrap; -webkit-box-align: center; align-items: center; position: relative;">content_copy import { [Component](https://angular.cn/api/core/Component), [OnInit](https://angular.cn/api/core/OnInit) } from '@angular/core'; import { Observable, Subject } from 'rxjs'; import { debounceTime, distinctUntilChanged, switchMap } from 'rxjs/operators'; import { Hero } from '../hero'; import { HeroService } from '../hero.service'; @[Component](https://angular.cn/api/core/Component)({ selector: 'app-hero-search', templateUrl: './hero-search.component.html', styleUrls: [ './hero-search.component.css' ] }) export class HeroSearchComponent implements [OnInit](https://angular.cn/api/core/OnInit) { heroes$: Observable<Hero[]>; private searchTerms = new Subject<string>(); constructor(private heroService: HeroService) {} // Push [a](https://angular.cn/api/router/RouterLinkWithHref) search term into the observable stream. search(term: string): void { this.searchTerms.next(term); } ngOnInit(): void { this.heroes$ = this.searchTerms.pipe( // wait 300ms after each keystroke before considering the term debounceTime(300), // ignore new term if same as previous term distinctUntilChanged(), // switch to new search observable each time the term changes switchMap((term: string) => this.heroService.searchHeroes(term)), ); } }</pre></aio-code></code-example>

注意,heroes$ 聲明為一個 Observable

<code-example path="toh-pt6/src/app/hero-search/hero-search.component.ts" region="heroes-stream" ng-version="5.2.0" style="clear: both; display: block; background-color: rgba(242, 242, 242, 0.2); border: 0.5px solid rgb(219, 219, 219); border-radius: 5px; color: rgb(51, 51, 51); margin: 16px auto; font-family: Roboto, "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><aio-code class="simple-code"><pre class="prettyprint lang-" style="display: flex; min-height: 32px; margin: 16px 24px; white-space: pre-wrap; -webkit-box-align: center; align-items: center; position: relative;">content_copy heroes$: Observable<Hero[]>;</pre></aio-code></code-example>

你將會在 ngOnInit() 中設置它晤郑,在此之前敌呈,先仔細看看 searchTerms 的定義。

RxJS Subject 類型的 searchTerms

searchTerms 屬性聲明成了 RxJS 的 Subject 類型造寝。

<code-example path="toh-pt6/src/app/hero-search/hero-search.component.ts" region="searchTerms" ng-version="5.2.0" style="clear: both; display: block; background-color: rgba(242, 242, 242, 0.2); border: 0.5px solid rgb(219, 219, 219); border-radius: 5px; color: rgb(51, 51, 51); margin: 16px auto; font-family: Roboto, "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><aio-code class="simple-code"><pre class="prettyprint lang-" style="display: flex; min-height: 32px; margin: 16px 24px; white-space: pre-wrap; -webkit-box-align: center; align-items: center; position: relative;">content_copy private searchTerms = new Subject<string>(); // Push [a](https://angular.cn/api/router/RouterLinkWithHref) search term into the observable stream. search(term: string): void { this.searchTerms.next(term); }</pre></aio-code></code-example>

Subject 既是可觀察對象的數(shù)據(jù)源磕洪,本身也是 Observable。 你可以像訂閱任何 Observable 一樣訂閱 Subject诫龙。

你還可以通過調(diào)用它的 next(value) 方法往 Observable 中推送一些值析显,就像 search() 方法中一樣。

search() 是通過對文本框的 keystroke 事件的事件綁定來調(diào)用的签赃。

<code-example path="toh-pt6/src/app/hero-search/hero-search.component.html" region="input" ng-version="5.2.0" style="clear: both; display: block; background-color: rgba(242, 242, 242, 0.2); border: 0.5px solid rgb(219, 219, 219); border-radius: 5px; color: rgb(51, 51, 51); margin: 16px auto; font-family: Roboto, "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><aio-code class="simple-code"><pre class="prettyprint lang-" style="display: flex; min-height: 32px; margin: 16px 24px; white-space: pre-wrap; -webkit-box-align: center; align-items: center; position: relative;">content_copy <input #searchBox id="search-box" (keyup)="search(searchBox.value)" /></pre></aio-code></code-example>

每當用戶在文本框中輸入時谷异,這個事件綁定就會使用文本框的值(搜索詞)調(diào)用 search() 函數(shù)。searchTerms 變成了一個能發(fā)出搜索詞的穩(wěn)定的流锦聊。

串聯(lián) RxJS 操作符

如果每當用戶擊鍵后就直接調(diào)用 searchHeroes() 將導致創(chuàng)建海量的 HTTP 請求歹嘹,浪費服務器資源并消耗大量網(wǎng)絡流量。

應該怎么做呢孔庭?ngOnInit()searchTerms 這個可觀察對象的處理管道中加入了一系列 RxJS 操作符尺上,用以縮減對 searchHeroes() 的調(diào)用次數(shù),并最終返回一個可及時給出英雄搜索結(jié)果的可觀察對象(每次都是 Hero[] )。

代碼如下:

<code-example path="toh-pt6/src/app/hero-search/hero-search.component.ts" region="search" ng-version="5.2.0" style="clear: both; display: block; background-color: rgba(242, 242, 242, 0.2); border: 0.5px solid rgb(219, 219, 219); border-radius: 5px; color: rgb(51, 51, 51); margin: 16px auto; font-family: Roboto, "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;"><aio-code class="simple-code"><pre class="prettyprint lang-" style="display: flex; min-height: 32px; margin: 16px 24px; white-space: pre-wrap; -webkit-box-align: center; align-items: center; position: relative;">content_copy this.heroes$ = this.searchTerms.pipe( // wait 300ms after each keystroke before considering the term debounceTime(300), // ignore new term if same as previous term distinctUntilChanged(), // switch to new search observable each time the term changes switchMap((term: string) => this.heroService.searchHeroes(term)), );</pre></aio-code></code-example>

  • 在傳出最終字符串之前尖昏,debounceTime(300) 將會等待仰税,直到新增字符串的事件暫停了 300 毫秒。 你實際發(fā)起請求的間隔永遠不會小于 300ms抽诉。

  • distinctUntilChanged 會確保只在過濾條件變化時才發(fā)送請求陨簇。

  • switchMap() 會為每個從 debouncedistinctUntilChanged 中通過的搜索詞調(diào)用搜索服務。 它會取消并丟棄以前的搜索可觀察對象迹淌,只保留最近的河绽。

借助 switchMap 操作符, 每個有效的擊鍵事件都會觸發(fā)一次 [HttpClient](https://angular.cn/api/common/http/HttpClient).get() 方法調(diào)用唉窃。 即使在每個請求之間都有至少 300ms 的間隔耙饰,仍然可能會同時存在多個尚未返回的 HTTP 請求。

switchMap() 會記住原始的請求順序纹份,只會返回最近一次 HTTP 方法調(diào)用的結(jié)果苟跪。 以前的那些請求都會被取消和舍棄。

注意蔓涧,取消前一個 searchHeroes() 可觀察對象并不會中止尚未完成的 HTTP 請求件已。 那些不想要的結(jié)果只會在它們抵達應用代碼之前被舍棄。

記住元暴,組件類中并沒有訂閱 heroes$ 這個可觀察對象篷扩,而是由模板中的 AsyncPipe 完成的。

試試看

再次運行本應用茉盏。在這個 儀表盤 中鉴未,在搜索框中輸入一些文字。如果你輸入的字符匹配上了任何現(xiàn)有英雄的名字鸠姨,你將會看到如下效果:

<figure style="background: rgb(255, 255, 255); padding: 20px; display: inline-block; box-shadow: rgba(0, 0, 0, 0.2) 2px 2px 5px 0px; margin: 0px 0px 14px; border-radius: 4px; color: rgba(0, 0, 0, 0.87); font-family: Roboto, "Helvetica Neue Light", "Helvetica Neue", Helvetica, Arial, "Lucida Grande", sans-serif; font-size: 14px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">
Hero Search Component

</figure>

這里出現(xiàn)了 | async

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末铜秆,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子讶迁,更是在濱河造成了極大的恐慌连茧,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,470評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件添瓷,死亡現(xiàn)場離奇詭異,居然都是意外死亡值纱,警方通過查閱死者的電腦和手機鳞贷,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,393評論 3 392
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來虐唠,“玉大人搀愧,你說我怎么就攤上這事。” “怎么了咱筛?”我有些...
    開封第一講書人閱讀 162,577評論 0 353
  • 文/不壞的土叔 我叫張陵搓幌,是天一觀的道長。 經(jīng)常有香客問我迅箩,道長溉愁,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,176評論 1 292
  • 正文 為了忘掉前任饲趋,我火速辦了婚禮拐揭,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘奕塑。我一直安慰自己堂污,他們只是感情好,可當我...
    茶點故事閱讀 67,189評論 6 388
  • 文/花漫 我一把揭開白布龄砰。 她就那樣靜靜地躺著盟猖,像睡著了一般。 火紅的嫁衣襯著肌膚如雪换棚。 梳的紋絲不亂的頭發(fā)上式镐,一...
    開封第一講書人閱讀 51,155評論 1 299
  • 那天,我揣著相機與錄音圃泡,去河邊找鬼碟案。 笑死,一個胖子當著我的面吹牛颇蜡,可吹牛的內(nèi)容都是我干的价说。 我是一名探鬼主播,決...
    沈念sama閱讀 40,041評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼风秤,長吁一口氣:“原來是場噩夢啊……” “哼鳖目!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起缤弦,我...
    開封第一講書人閱讀 38,903評論 0 274
  • 序言:老撾萬榮一對情侶失蹤领迈,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后碍沐,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體狸捅,經(jīng)...
    沈念sama閱讀 45,319評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,539評論 2 332
  • 正文 我和宋清朗相戀三年累提,在試婚紗的時候發(fā)現(xiàn)自己被綠了尘喝。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,703評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡斋陪,死狀恐怖朽褪,靈堂內(nèi)的尸體忽然破棺而出置吓,到底是詐尸還是另有隱情,我是刑警寧澤缔赠,帶...
    沈念sama閱讀 35,417評論 5 343
  • 正文 年R本政府宣布衍锚,位于F島的核電站,受9級特大地震影響嗤堰,放射性物質(zhì)發(fā)生泄漏戴质。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,013評論 3 325
  • 文/蒙蒙 一梁棠、第九天 我趴在偏房一處隱蔽的房頂上張望置森。 院中可真熱鬧,春花似錦符糊、人聲如沸凫海。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,664評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽行贪。三九已至,卻和暖如春模闲,著一層夾襖步出監(jiān)牢的瞬間建瘫,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,818評論 1 269
  • 我被黑心中介騙來泰國打工尸折, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留啰脚,地道東北人。 一個月前我還...
    沈念sama閱讀 47,711評論 2 368
  • 正文 我出身青樓实夹,卻偏偏與公主長得像橄浓,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子亮航,可洞房花燭夜當晚...
    茶點故事閱讀 44,601評論 2 353