ngRx 官方示例分析 - 4.pages

?Page 中通過構造函數注入 Store,基于 Store 進行數據操作。

注意 Component 使用了?changeDetection: ChangeDetectionStrategy.OnPush.

OnPush?means that the change detector's mode will be set to?CheckOnce?during hydration.

?

/app/containers/collection-page.ts

import 'rxjs/add/operator/let';
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs/Observable';import * as fromRoot from '../reducers';
import { Book } from '../models/book';@Component({selector: 'bc-collection-page',changeDetection: ChangeDetectionStrategy.OnPush,template: `<md-card><md-card-title>My Collection</md-card-title></md-card><bc-book-preview-list [books]="books$ | async"></bc-book-preview-list>
  `,/*** Container components are permitted to have just enough styles* to bring the view together. If the number of styles grow,* consider breaking them out into presentational* components.*/styles: [`md-card-title {display: flex;justify-content: center;}`]
})
export class CollectionPageComponent {books$: Observable<Book[]>;constructor(store: Store<fromRoot.State>) {this.books$ = store.select(fromRoot.getBookCollection);}
}

/app/containers/find-book-page.ts

import 'rxjs/add/operator/let';
import 'rxjs/add/operator/take';
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs/Observable';import * as fromRoot from '../reducers';
import * as book from '../actions/book';
import { Book } from '../models/book';@Component({selector: 'bc-find-book-page',changeDetection: ChangeDetectionStrategy.OnPush,template: `<bc-book-search [query]="searchQuery$ | async" [searching]="loading$ | async" (search)="search($event)"></bc-book-search><bc-book-preview-list [books]="books$ | async"></bc-book-preview-list>
  `
})
export class FindBookPageComponent {searchQuery$: Observable<string>;books$: Observable<Book[]>;loading$: Observable<boolean>;constructor(private store: Store<fromRoot.State>) {this.searchQuery$ = store.select(fromRoot.getSearchQuery).take(1);this.books$ = store.select(fromRoot.getSearchResults);this.loading$ = store.select(fromRoot.getSearchLoading);}search(query: string) {this.store.dispatch(new book.SearchAction(query));}
}

?注意,點擊搜索之后,我們回派發一個 Search 的 Action,但是,在 Book 的 Reducer 中并不處理這個 Action, @ngrx/effect 將會監控這個 Action,進行異步處理。

/app/containers/not-found-page.ts

import { Component, ChangeDetectionStrategy } from '@angular/core';@Component({selector: 'bc-not-found-page',changeDetection: ChangeDetectionStrategy.OnPush,template: `<md-card><md-card-title>404: Not Found</md-card-title><md-card-content><p>Hey! It looks like this page doesn't exist yet.</p></md-card-content><md-card-actions><button md-raised-button color="primary" routerLink="/">Take Me Home</button></md-card-actions></md-card>`,styles: [`:host {text-align: center;}`]
})
export class NotFoundPageComponent { }

?通過 @Input() 參數將數據從頁面傳遞給下面的 Component,事件從底層 Component 冒泡上來。

/app/containers/selected-book-page.ts

import { Component, ChangeDetectionStrategy } from '@angular/core';
import { Store } from '@ngrx/store';
import { Observable } from 'rxjs/Observable';import * as fromRoot from '../reducers';
import * as collection from '../actions/collection';
import { Book } from '../models/book';@Component({selector: 'bc-selected-book-page',changeDetection: ChangeDetectionStrategy.OnPush,template: `<bc-book-detail[book]="book$ | async"[inCollection]="isSelectedBookInCollection$ | async"(add)="addToCollection($event)"(remove)="removeFromCollection($event)"></bc-book-detail>
  `
})
export class SelectedBookPageComponent {book$: Observable<Book>;isSelectedBookInCollection$: Observable<boolean>;constructor(private store: Store<fromRoot.State>) {this.book$ = store.select(fromRoot.getSelectedBook);this.isSelectedBookInCollection$ = store.select(fromRoot.isSelectedBookInCollection);}addToCollection(book: Book) {this.store.dispatch(new collection.AddBookAction(book));}removeFromCollection(book: Book) {this.store.dispatch(new collection.RemoveBookAction(book));}
}

?

/app/containers/view-book-page.ts

import '@ngrx/core/add/operator/select';
import 'rxjs/add/operator/map';
import { Component, OnDestroy, ChangeDetectionStrategy } from '@angular/core';
import { ActivatedRoute } from '@angular/router';
import { Store } from '@ngrx/store';
import { Subscription } from 'rxjs/Subscription';import * as fromRoot from '../reducers';
import * as book from '../actions/book';/*** Note: Container components are also reusable. Whether or not* a component is a presentation component or a container* component is an implementation detail.** The View Book Page's responsibility is to map router params* to a 'Select' book action. Actually showing the selected* book remains a responsibility of the* SelectedBookPageComponent*/
@Component({selector: 'bc-view-book-page',changeDetection: ChangeDetectionStrategy.OnPush,template: `<bc-selected-book-page></bc-selected-book-page>
  `
})
export class ViewBookPageComponent implements OnDestroy {actionsSubscription: Subscription;constructor(store: Store<fromRoot.State>, route: ActivatedRoute) {this.actionsSubscription = route.params.select<string>('id').map(id => new book.SelectAction(id)).subscribe(store);}ngOnDestroy() {this.actionsSubscription.unsubscribe();}
}

?

/app/containers/app.ts

import 'rxjs/add/operator/let';
import { Observable } from 'rxjs/Observable';
import { Component, ChangeDetectionStrategy } from '@angular/core';
import { Store } from '@ngrx/store';import * as fromRoot from '../reducers';
import * as layout from '../actions/layout';@Component({selector: 'bc-app',changeDetection: ChangeDetectionStrategy.OnPush,template: `<bc-layout><bc-sidenav [open]="showSidenav$ | async"><bc-nav-item (activate)="closeSidenav()" routerLink="/" icon="book" hint="View your book collection">My Collection</bc-nav-item><bc-nav-item (activate)="closeSidenav()" routerLink="/book/find" icon="search" hint="Find your next book!">Browse Books</bc-nav-item></bc-sidenav><bc-toolbar (openMenu)="openSidenav()">Book Collection</bc-toolbar><router-outlet></router-outlet></bc-layout>
  `
})
export class AppComponent {showSidenav$: Observable<boolean>;constructor(private store: Store<fromRoot.State>) {/*** Selectors can be applied with the `select` operator which passes the state* tree to the provided selector*/this.showSidenav$ = this.store.select(fromRoot.getShowSidenav);}closeSidenav() {/*** All state updates are handled through dispatched actions in 'container'* components. This provides a clear, reproducible history of state* updates and user interaction through the life of our* application.*/this.store.dispatch(new layout.CloseSidenavAction());}openSidenav() {this.store.dispatch(new layout.OpenSidenavAction());}
}

?

轉載于:https://www.cnblogs.com/haogj/p/6537286.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/255049.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/255049.shtml
英文地址,請注明出處:http://en.pswp.cn/news/255049.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

用ffmpeg把yuv格式轉化為mpeg格式

http://blog.sina.com.cn/s/blog_5f5ad6a90100cs5k.html

方法:查詢MongoDB數據庫中最新一條數據(JAVA)

使用JAVA語言查詢MongoDB中某個數據庫某個集合的最新一條數據&#xff1a; MongoCollection<Document> cpu MongoClient.getDatabase("sysmgr").getCollection("cpu"); //獲取所需集合 Document dbo cpu.find().sort(descending("time"…

NoPause/NoEmgAbort的任務 與后臺任務的區別

NoPause/NoEmgAbort的任務示例 下面的例子顯示了一個程序&#xff0c;可以監視控制器的錯誤并根據錯誤編號在發生錯誤時切換I/O On/Off。 Function main Xqt ErrorMonitor, NoEmgAbort : FendFunction ErrorMonitor Wait ErrorOnIf 4000 < SysErr And Syserr < 5999 T…

30分鐘搞定后臺登錄界面(103個后臺PSD源文件、素材網站)(轉)

出處&#xff1a;http://www.cnblogs.com/best/p/6582294.html 目錄 一、界面預覽二、PSD源文件預覽三、工具分享四、資源說明五、素材下載網站六、下載去年八月時要做一個OA系統為了后臺界面而煩惱&#xff0c;后來寫了一篇博客&#xff08;《后臺管理UI的選擇》&#xff09;介…

Linux 查看服務器開放的端口號

在討論這個問題前&#xff0c;我們先來了解一下物理端口、邏輯端口、端口號等計算機概念。 端口相關的概念&#xff1a; 在網絡技術中&#xff0c;端口&#xff08;Port&#xff09;包括邏輯端口和物理端口兩種類型。物理端口指的是物理存在的端口&#xff0c;如ADSL Modem、集…

VC的文件路徑為什么要用雙斜杠

在編程時&#xff0c;打開文件的路徑在用單斜杠時&#xff0c;會出現問題&#xff0c;例如&#xff1a; image cvLoadImage("C:\Users\lyb\Documents\Visual Studio 2013\Projects\smooth\Debug\pic.png", 0);這樣的寫法在編譯時&#xff0c;不會出現編譯錯誤&#…

FFMpeg中apiexample.c例子分析——解碼分析

FFMpeg中apiexample.c例子分析——解碼分析 收藏 我們直接從 video_decode_example() 函數開始講&#xff0c;該函數實現了如何去解碼一個視頻文件&#xff0c;以 .mpeg 文 件為例。 &#xff08; 1 &#xff09;將緩存的末尾清 0 &#xff0c;從而確保讀操作不會越界導致破…

[轉]整理一些好的開源項目

首先說明&#xff0c;要想找開源項目&#xff0c;當然是Github&#xff01; 另外oschina上面也可能有你要的&#xff0c;這個是分類的鏈接&#xff1a;http://www.oschina.net/project/tags&#xff0c;比如這個是一個Python的相關開源資源&#xff1a;http://www.oschina.net/…

android是32-bit系統還是64-bit系統

轉自&#xff1a;http://www.cnblogs.com/pengwang/archive/2013/03/11/2954496.html 電腦CPU分32位和64位&#xff0c;這個我們都知道。用了這么長時間的android手機&#xff0c;突然有個疑問&#xff1a;android OS運行在多少位的CPU上呢&#xff1f; android應用程序是基于D…

海爾系列報道之一:海爾“小微”怎么玩

海爾去年裁了1.6萬人&#xff0c;今年上半年裁了5000人&#xff0c;這2.1萬人去了哪&#xff1f;除了被淘汰的部分&#xff0c;他們中的大多數去了169家小微公司. 從今年年初開始&#xff0c;海爾集團品牌總監范建斌就帶著海爾品牌部的兩個姑娘開始籌劃做一個文化小微公司&…

FFMpeg中apiexample.c例子分析——編碼分析

FFMpeg中apiexample.c例子分析——編碼分析apiexample.c例子教我們如何去利用ffmpeg庫中的api函數來自己編寫編解碼程序。 &#xff08;1&#xff09;首先&#xff0c;main函數中一開始會去調用avcodec_init()函數&#xff0c;該函數的作用是初始化libavcodec&#xff0c;而我們…

.net 常見異常及其翻譯

System.Exception//所有異常的基類型System.ApplicationException//發生非致命應用程序錯誤時引發的異常System.SystemException//為System命名空間中的預定義異常定義基類System.SystemException//異常根類System.AccessViolationException//在試圖讀寫受保護內存時引發的異常…

Access2010打開系統表MSysObjects的控制權限

一、顯示系統表 第一步&#xff1a;單擊左上角【文件】頁簽&#xff0c;點擊【選項】打開選項對話框&#xff0c;如圖所示 第二步&#xff1a;在【Access選項】對話框中&#xff0c;選擇【當前數據庫】&#xff0c;在【導航】欄下&#xff0c;點擊【導航選項】打開【導航選項】…

抓屏的各種方法(http://www.codeproject.com/KB/dialog/screencap.aspx)

文章翻譯自 P.GopalaKrishna 的 Various methods for capturing the screen 一文&#xff0c;原版地址見下面。本文章版權歸原作者所有。 如果轉載該譯文 , 請保證文章的完整性&#xff0c;并注明來自 www.farproc.com 袁曉輝 2005/6/12 原版地址&…

與 OpenCV 1 同時使用

與 OpenCV 1 同時使用 目的 對于OpenCV的開發團隊來說&#xff0c;持續穩定地提高代碼庫非常重要。我們一直在思考如何在使其易用的同時保持靈活性。新的C接口即為此而來。盡管如此&#xff0c;向下兼容仍然十分重要。我們并不想打斷你基于早期OpenCV庫的開發。因此&am…

第五周 Leetcode 99. Recover Binary Search Tree (HARD)

Leetcode99 給定一個 二叉搜索樹&#xff0c;其中兩個節點被交換&#xff0c;寫一個程序恢復這顆BST. 只想到了時間復雜度O&#xff08;n&#xff09;空間復雜度O&#xff08;h&#xff09; h為樹高的解法&#xff0c;還沒想到空間O(1&#xff09;的解法。 交換的情況只有兩種&…

Fedora15安裝NVIDIA顯卡驅動全過程

Fedora安裝N卡驅動全過程 Fedora安裝NVIDIA顯卡全過程&#xff0c;經過自己親自安裝 折騰了一個上午&#xff0c;搞定了N卡驅動安裝&#xff0c;現將安裝步驟整理如下&#xff1a; 1、首先訪問Nvidia官網下載最新的Linux驅動&#xff1a;http://www.nvidia.cn/Download/index…

板鄧:wordpress自定義登錄頁面實現用戶登錄

首先檢查用戶是否已經登錄&#xff0c;如果已經登錄就返回info目錄下的頁面。 <?phpglobal $current_user;$loginuserid $current_user->ID;if($loginuserid){//如果已經登錄header("Location:".get_bloginfo(url)."/info/"); exit;} 如果用戶未登…

機器學習(machine learning)之AdaBoost算法

轉自&#xff1a;http://blog.csdn.net/haidao2009/article/details/7514787 淺談 Adaboost 算法 機器學習是利用一些方法來使機器實現人的學習行為&#xff0c;以便獲取新的知識或技能&#xff0c;重新組織已有的知識結構使之不斷改善自身的性能。 AdaBoost全名“adaptive B…