本文整理匯總了TypeScript中rxjs/BehaviorSubject.BehaviorSubject.distinctUntilChanged方法的典型用法代碼示例。如果您正苦於以下問題:TypeScript BehaviorSubject.distinctUntilChanged方法的具體用法?TypeScript BehaviorSubject.distinctUntilChanged怎麽用?TypeScript BehaviorSubject.distinctUntilChanged使用的例子?那麽, 這裏精選的方法代碼示例或許可以為您提供幫助。您也可以進一步了解該方法所在類rxjs/BehaviorSubject.BehaviorSubject
的用法示例。
在下文中一共展示了BehaviorSubject.distinctUntilChanged方法的4個代碼示例,這些例子默認根據受歡迎程度排序。您可以為喜歡或者感覺有用的代碼點讚,您的評價將有助於係統推薦出更棒的TypeScript代碼示例。
示例1: StoreService
function StoreService(): D1StoreServiceType {
'ngInject';
let _stores: D1Store[] = [];
// A subject that keeps track of the current account. Because it's a
// behavior subject, any new subscriber will always see its last
// value.
const accountStream = new BehaviorSubject<DestinyAccount | null>(null);
// The triggering observable for force-reloading stores.
const forceReloadTrigger = new Subject();
// A stream of stores that switches on account changes and supports reloading.
// This is a ConnectableObservable that must be connected to start.
const storesStream = accountStream
// Only emit when the account changes
.distinctUntilChanged(compareAccounts)
// But also re-emit the current value of the account stream
// whenever the force reload triggers
.merge(forceReloadTrigger.switchMap(() => accountStream.take(1)))
// Whenever either trigger happens, load stores
.switchMap(loadingTracker.trackPromise(loadStores))
// Keep track of the last value for new subscribers
.publishReplay(1);
// TODO: If we can make the store structures immutable, we could use
// distinctUntilChanged to avoid emitting store updates when
// nothing changed!
const service = {
getActiveStore: () => _stores.find((s) => s.current),
getStores: () => _stores,
getStore: (id) => _stores.find((s) => s.id === id),
getVault: () => _stores.find((s) => s.isVault) as D1Vault | undefined,
getAllItems: () => _.flatMap(_stores, (s) => s.items),
refreshRatingsData() {
return;
},
getStoresStream,
getItemAcrossStores,
updateCharacters,
reloadStores,
touch() {
store.dispatch(update({ stores: _stores }));
}
};
return service;
/**
* Find an item among all stores that matches the params provided.
*/
function getItemAcrossStores(params: {
id?: string;
hash?: number;
notransfer?: boolean;
amount?: number;
}) {
const predicate = _.iteratee(_.pick(params, 'id', 'hash', 'notransfer', 'amount')) as (
i: DimItem
) => boolean;
for (const store of _stores) {
const result = store.items.find(predicate);
if (result) {
return result;
}
}
return undefined;
}
/**
* Update the high level character information for all the stores
* (level, light, int/dis/str, etc.). This does not update the
* items in the stores - to do that, call reloadStores.
*/
function updateCharacters(account: DestinyAccount) {
// TODO: the router.globals.params defaults are just for now, to bridge callsites that don't know platform
if (!account) {
if (router.globals.params.membershipId && router.globals.params.platformType) {
account = {
membershipId: router.globals.params.membershipId,
platformType: router.globals.params.platformType,
displayName: 'Unknown',
platformLabel: 'Unknown',
destinyVersion: 1
};
} else {
throw new Error("Don't know membership ID and platform type");
}
}
return Promise.all([getDefinitions(), getCharacters(account)]).then(([defs, bungieStores]) => {
_stores.forEach((dStore) => {
if (!dStore.isVault) {
const bStore = bungieStores.find((s) => s.id === dStore.id)!;
dStore.updateCharacterInfo(defs, bStore.base);
}
});
service.touch();
//.........這裏部分代碼省略.........
示例2: BehaviorSubject
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
import '../rx-operators';
import { IPromise, IDeferred } from 'angular';
const subject = new BehaviorSubject(false);
export const loadingTrackerStream = subject.distinctUntilChanged().shareReplay(1);
export default function loadingTracker(promiseTracker) {
'ngInject';
const tracker = promiseTracker();
return {
addPromise(promise: IPromise<any>) {
const fullPromise: IDeferred<any> = tracker.addPromise(promise);
subject.next(true);
fullPromise.promise.finally(() => {
setTimeout(() => subject.next(this.active()), 0);
});
},
active() {
return tracker.active();
}
};
}
示例3: makeD2StoresService
/**
* TODO: For now this is a copy of StoreService customized for D2. Over time we should either
* consolidate them, or at least organize them better.
*/
function makeD2StoresService(): D2StoreServiceType {
'ngInject';
let _stores: D2Store[] = [];
// A subject that keeps track of the current account. Because it's a
// behavior subject, any new subscriber will always see its last
// value.
const accountStream = new BehaviorSubject<DestinyAccount | null>(null);
// The triggering observable for force-reloading stores.
const forceReloadTrigger = new Subject();
// A stream of stores that switches on account changes and supports reloading.
// This is a ConnectableObservable that must be connected to start.
const storesStream = accountStream
// Only emit when the account changes
.distinctUntilChanged(compareAccounts)
// But also re-emit the current value of the account stream
// whenever the force reload triggers
.merge(forceReloadTrigger.switchMap(() => accountStream.take(1)))
// Whenever either trigger happens, load stores
.switchMap(loadStores)
// Keep track of the last value for new subscribers
.publishReplay(1);
// TODO: If we can make the store structures immutable, we could use
// distinctUntilChanged to avoid emitting store updates when
// nothing changed!
const service = {
getActiveStore: () => _stores.find((s) => s.current),
getStores: () => _stores,
getStore: (id: string) => _stores.find((s) => s.id === id),
getVault: () => _stores.find((s) => s.isVault) as D2Vault | undefined,
getAllItems: () => flatMap(_stores, (s) => s.items),
getStoresStream,
getItemAcrossStores,
updateCharacters,
reloadStores,
refreshRatingsData,
touch() {
store.dispatch(update(_stores));
}
};
return service;
/**
* Find an item among all stores that matches the params provided.
*/
function getItemAcrossStores(params: {
id?: string;
hash?: number;
notransfer?: boolean;
amount?: number;
}) {
const predicate = _.iteratee(_.pick(params, 'id', 'hash', 'notransfer', 'amount')) as (
i: DimItem
) => boolean;
for (const store of _stores) {
const result = store.items.find(predicate);
if (result) {
return result;
}
}
return undefined;
}
/**
* Update the high level character information for all the stores
* (level, light, int/dis/str, etc.). This does not update the
* items in the stores - to do that, call reloadStores.
*/
function updateCharacters(account: DestinyAccount): IPromise<D2Store[]> {
// TODO: the router.globals.params defaults are just for now, to bridge callsites that don't know platform
if (!account) {
if (router.globals.params.membershipId && router.globals.params.platformType) {
account = {
membershipId: router.globals.params.membershipId,
platformType: router.globals.params.platformType,
displayName: 'Unknown',
platformLabel: 'Unknown',
destinyVersion: 2
};
} else {
throw new Error("Don't know membership ID and platform type");
}
}
return $q
.all([getDefinitions(), getCharacters(account)])
.then(([defs, profileInfo]: [D2ManifestDefinitions, DestinyProfileResponse]) => {
// TODO: create a new store
_stores.forEach((dStore) => {
if (!dStore.isVault) {
//.........這裏部分代碼省略.........
示例4: VendorService
function VendorService(): VendorServiceType {
let _ratingsRequested = false;
const service: VendorServiceType = {
vendorsLoaded: false,
getVendorsStream,
reloadVendors,
getVendors() {
return this.vendors;
},
// By hash
vendors: {},
totalVendors: 0,
loadedVendors: 0,
requestRatings,
countCurrencies
// TODO: expose getVendor promise, idempotently?
};
// A subject that keeps track of the current account. Because it's a
// behavior subject, any new subscriber will always see its last
// value.
const accountStream = new BehaviorSubject<DestinyAccount | null>(null);
// A stream of stores that switches on account changes and supports reloading.
// This is a ConnectableObservable that must be connected to start.
const vendorsStream = accountStream
// Only emit when the account changes
.distinctUntilChanged(compareAccounts)
.do(() => {
service.vendors = {};
service.vendorsLoaded = false;
})
.switchMap(
(account) => D1StoresService.getStoresStream(account!),
(account, stores) => [account!, stores!]
)
.filter(([_, stores]) => Boolean(stores))
.switchMap(([account, stores]: [DestinyAccount, D1Store[]]) => loadVendors(account, stores))
// Keep track of the last value for new subscribers
.publishReplay(1);
const clearVendors = _.once(() => {
D1ManifestService.newManifest$.subscribe(() => {
service.vendors = {};
service.vendorsLoaded = false;
deleteCachedVendors();
});
});
return service;
function deleteCachedVendors() {
// Everything's in one table, so we can't just clear
keys().then((keys) => {
keys.forEach((key) => {
if (key.toString().startsWith('vendor')) {
del(key);
}
});
});
}
/**
* Set the current account, and get a stream of vendor and stores updates.
* This will keep returning data even if something else changes
* the account by also calling "vendorsStream". This won't force the
* vendors to reload unless they haven't been loaded at all.
*
* @return a stream of vendor updates
*/
function getVendorsStream(account: DestinyAccount) {
accountStream.next(account);
// Start the stream the first time it's asked for. Repeated calls
// won't do anything.
vendorsStream.connect();
clearVendors(); // Install listener to clear vendors
return vendorsStream;
}
function reloadVendors() {
D1StoresService.reloadStores();
}
/**
* Returns a promise for a fresh view of the vendors and their items.
*/
function loadVendors(
account: DestinyAccount,
stores: D1Store[]
): Promise<[D1Store[], { [vendorHash: number]: Vendor }]> {
const characters = stores.filter((s) => !s.isVault);
const reloadPromise = getDefinitions()
.then((defs) => {
// Narrow down to only visible vendors (not packages and such)
const vendorList = Object.values(defs.Vendor).filter((v) => v.summary.visible);
service.totalVendors = characters.length * (vendorList.length - vendorBlackList.length);
service.loadedVendors = 0;
//.........這裏部分代碼省略.........