我正在玩管道和订阅.如果我使用带有水龙头的管道,则没有任何东西会登录控制台.如果我使用订阅,它正在工作.那么我做错了什么?
import { Observable } from 'rxjs';
import { tap, take } from 'rxjs/operators';
this.store.select(state => state.auth.authUser).pipe(
take(1),
tap((data) => {
//Not Working - no console output
console.log('[Tap] User Data', data);
})
);
this.store.select(state => state.auth.authUser).subscribe((data) => {
// Working - user data output in console
console.log('[Subscribe] User Data', data);
})
Run Code Online (Sandbox Code Playgroud)
我在Angular 6中使用RxJs 6,TypeScript和ngxs作为存储.
我有一个警卫,检查状态是否有令牌.
canActivate(): boolean {
const token = this.store.selectSnapshot((state: AuthenticationState) => state.token);
if (!token) {
return true;
}
this.router.navigate(['home']);
return false;
}
Run Code Online (Sandbox Code Playgroud)
然后我有这样的事情:
export class AuthenticationState {
@Selector()
static token(state: AuthenticationStateModel) {
return state.token;
}
}
Run Code Online (Sandbox Code Playgroud)
我收到一个错误.'AuthenticationState'类型上不存在属性'token'
我想在我的Angular 6应用程序中使用ngxs进行状态管理.
但我不确定大项目是否成熟.
我找不到任何关于ngrx和ngxs之间性能差异的文章.有人可以提供一些信息吗?
性能指标:从商店中获取大量商品并将其写回商店.
所以我通常有一种在点击时调度操作的方法:
create() {
this.store.dispatch(new Create(this.form.value));
}
Run Code Online (Sandbox Code Playgroud)
此代码触发以下场景,并根据请求是否失败调度 CreateSuccess 或 CreateFailed
@Action(Create)
create({ dispatch }: StateContext<StateInterface>, { entity}: Create) {
return this.http.post('mybackend', entity).pipe(
tap<EntityType>(resp => dispatch(new CreateSuccess(resp))),
catchError(error => dispatch(new CreateFailed(error)))
);
}
Run Code Online (Sandbox Code Playgroud)
现在,在我调用的组件内,create()
我正在监听这两个操作。
this.actions$.pipe(
ofActionSuccessful(CreateSuccess, UpdateSuccess),
takeUntil(componentDestroyed(this)) // <--
).subscribe(action => doStuff());
Run Code Online (Sandbox Code Playgroud)
这一切都完美地工作,唯一困扰我的是每次我使用它时,我都必须添加 takeUntil() 部分,以便在组件被销毁时取消订阅。
我知道这对每个人来说可能不是一个真正的问题,但我想知道是否有更干净的方法来做到这一点。
我考虑过一个自定义的 RxJS 运算符可以处理这个问题,但也许还有其他选项,或者(我还没有找到任何相关内容),NGXS 有没有办法自行取消订阅?
情况:我有一个由前端Angular应用程序构成的微型前端,并且将许多Angular库作为模块导入,这些模块包含充当“子应用程序”的组件。
目标:我想在所有子应用程序之间共享在主机应用程序中创建的NGXS存储,以便每个子应用程序都有自己的全局状态片段,并且也可以访问全局状态。
在主机应用程序中,我正在创建状态,如下所示:
@State<ApplicationStateModel>({
name: 'host',
defaults: {
context: {
language: 'en'
},
apps: {}
}
})
export class ApplicationState {...}
Run Code Online (Sandbox Code Playgroud)
并且在子应用程序中,我希望能够发送动作以及切分此状态,例如:
constructor(private store: Store) {
// slice the context
this.context$ = this.store.select(state => state.host.context);
// slice this sub-app state
this.state$ = this.store.select(state => state.host.apps['myapp']);
}
...
// dispatch an action
this.store.dispatch(new UpdateContext());
Run Code Online (Sandbox Code Playgroud)
问题:如何将商店从主机应用程序传递到子应用程序?我猜可能有一种方法可以通过在导入过程中使用模块的.forRoot()
或.forFeature()
函数来实现。但是我完全迷失了。
我想用两种方式处理 NGXS 中的错误。第一种方法是处理组件中存储调度的错误。第二种方法是全局角度错误处理程序,作为错误未处理时的后备(第一种方法未处理)。
但问题是,当操作处理程序中出现错误时,NGRX 总是会调用全局错误处理程序。
因此,在组件中给出以下代码:
this.store.dispatch(new FetchAction())
.subscribe( error: () => console.log('fetch error occured'))
Run Code Online (Sandbox Code Playgroud)
这个动作处理程序:
fetch() {
return this.http.get('..');
}
Run Code Online (Sandbox Code Playgroud)
和这个全局错误处理程序:
export class GlobalErrorHandler extends ErrorHandler {
handleError(err: any) {
console.log('unexpected error occured');
}
}
Run Code Online (Sandbox Code Playgroud)
控制台中会出现两条错误消息。一份来自调度的订阅,一份来自全局错误处理程序,因为操作处理程序中存在错误。
现在我可以在操作处理程序中捕获错误,但这将是错误的地方,因为操作处理程序不应该知道该操作的错误是在组件中处理的。
我做了一个 stackblitz,单击按钮时在控制台中显示两个错误:https ://stackblitz.com/edit/ngxs-error-throw-r42fkb?file=src/app/app.component.ts
我创建了一个新的 Angular 应用程序 (v15.2.0),并添加了 @ngxs/store (v3.7.6)\n可以在此处查看详细的 package.lock
\n{\n ...\n "dependencies": {\n "@angular/animations": "^15.2.0",\n "@angular/common": "^15.2.0",\n "@angular/compiler": "^15.2.0",\n "@angular/core": "^15.2.0",\n "@angular/forms": "^15.2.0",\n "@angular/platform-browser": "^15.2.0",\n "@angular/platform-browser-dynamic": "^15.2.0",\n "@angular/router": "^15.2.0",\n "@ng-bootstrap/ng-bootstrap": "^14.0.1",\n "@ngxs/store": "^3.7.6", <-- added by me\n "ngx-cookie-service": "^15.0.0", <-- added by me\n "font-awesome": "^4.7.0", <-- added by me\n "bootstrap": "^5.2.3", <-- added by me\n "rxjs": "~7.8.0",\n "tslib": "^2.3.0",\n "zone.js": "~0.12.0"\n },\n "devDependencies": { <-- all ar the default ones\n "@angular-devkit/build-angular": "^15.2.1",\n "@angular/cli": "~15.2.1",\n "@angular/compiler-cli": "^15.2.0",\n "@types/jasmine": "~4.3.0",\n "jasmine-core": "~4.5.0",\n "karma": …
Run Code Online (Sandbox Code Playgroud) 想知道为什么会使用NGRX或NGXS作为Angular应用程序而不是构造函数注入服务来处理组件IO?
是否只是为了确保组件属性引用永远不会在不切换整个属性值引用的情况下进行变异,或者还有更多内容?
根据我开发的答案:
切片.
我相信它可以完成NgRx/NgXS所做的一切(除了时间机器 - 但这很容易通过增量通知实现 - 已经支持).但是没有样板.
这篇文章展示了一些功能:https: //medium.com/@ole.ersoy/storing-users-in-the-reactive-slice-object-store-5ea0fab06256
我正在使用 Angular 和 NestJS 构建一个应用程序,并使用 NGXS 进行状态管理。我完成了所有设置并为我的应用程序提供服务,并在控制台中收到此错误。
从源“ http://localhost:4200 ”访问“localhost:333/api/product-index”处的 XMLHttpRequest已被 CORS 策略阻止:跨源请求仅支持协议方案:http、data、chrome、chrome - 扩展名,https。
经过一番研究后,我发现这篇文章解释了如何在我们的 Angular 应用程序中处理 CORS,在检查了它告诉我们要修改的文件后,我发现这些设置已经存在。我对它告诉我们要更新的文件感到困惑server.js
,在研究了文件中通常执行的操作后,server.js
我得出的结论是,在 Angular 中它一定是该main.ts
文件,但我不知道是否需要对文件进行main.ts
修改在我的 Nest 应用程序或我的 Angular 应用程序中。nrwl nx
我也在我的应用程序中使用monorepo。
这是proxy.conf.json
我的角度应用程序中的文件
{
"/cre8or-maker-backend": {
"target": "http://localhost:3333",
"secure": false,
"logLevel": "debug"
}
}
Run Code Online (Sandbox Code Playgroud)
这是我文件中对象serve
的对象。architect
angular.json
"serve": {
"builder": "@angular-devkit/build-angular:dev-server",
"options": {
"browserTarget": "cre8or-maker:build",
"proxyConfig": "apps/cre8or-maker/proxy.conf.json"
}
Run Code Online (Sandbox Code Playgroud)
正如我之前所说,这些设置已经存在于这些文件中,对我来说唯一新鲜的是关于修改文件的部分server.js
,我假设是main.ts
Angular 世界中的文件。这是我的main.ts
文件的样子
nest main.ts
import { …
Run Code Online (Sandbox Code Playgroud) 在我拥有这个运行良好的解析器之前:
resolve() {
return forkJoin(
this.getData1(),
this.getData2(),
this.getData3()
);
}
Run Code Online (Sandbox Code Playgroud)
现在我必须做一些实际上不起作用的事情:
resolve() {
return this.actions$
.pipe(
ofActionSuccessful(SomeSctonSuccess),
forkJoin(
this.getData1(),
this.getData2(),
this.getData3()
)
);
}
Run Code Online (Sandbox Code Playgroud)
因为我遇到了这个错误:
“Observable<[any, any, any, any]>”类型的参数不可分配给“OperatorFunction”类型的参数。类型 'Observable<[any, any, any, any]>' 不匹配签名 '(source: Observable): Observable'。
任何想法如何解决?
现在我注意在发生forkJoin
后返回我的唯一https://ngxs.gitbook.io/ngxs/advanced/action-handlersofActionSuccessful(SomeSctonSuccess)