- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我通常只是浏览现有的问题就能找到我做错了什么,但在这里,没有任何帮助。
我正在使用一个简单的 Ng2 模块来尝试列出和更新 NeDB 存储的内容。
请注意,我对 NeDB 商店没有任何问题,我已确认它已正确更新,并且最初已正确加载,所以我的问题出在其他地方。
我遇到的问题如下:
"the async pipe doesn't work".
我有这个模块。
@NgModule({
imports: [CommonModule],
exports: [],
declarations: [WikiComponent],
providers: [WikiDbService],
})
export class WikiModule { }
我有这个组件。
@Component({
selector: 'wiki',
templateUrl: './wiki.component.html'
})
export class WikiComponent implements OnInit {
items: Observable<WikiItem[]>;
constructor(private _db : WikiDbService) { }
ngOnInit() {
this.items = this._db.items;
this.items.subscribe({
next: x => console.log("got value", x),
error: e => console.error("observable error", e),
complete: () => console.log("done")
});
}
}
我有这个模板。
<p>{{items | async | json}}</p>
<ul>
<li *ngFor="let item of (items | async)">{{item.name}}</li>
</ul>
<input #newName (keyup)="0">
<button (click)="_db.addByName(newName.value)">ADD</button>
我有这项服务。
@Injectable()
export class WikiDbService {
private sub: BehaviorSubject<WikiItem[]> = new BehaviorSubject<WikiItem[]>([]);
private db: DataStore;
public items: Observable<WikiItem[]> = this.sub.asObservable();
constructor() {
console.log("BehaviorSubject", this.sub);
console.log("Observable", this.items);
this.db = new DataStore(
{
filename: path.join(app.getAppPath(),"wiki.db"),
autoload: true,
onload:
(err)=>{
if(!err) {
this.db.find<WikiItem>({},
(e,docs) => {
if(!e) {
this.sub.next(docs);
}
})
}
}
});
}
public add(v: WikiItem) {
this.db.insert(
v,
(e, nDoc) =>
{
if(!e) {
this.sub.next([...this.sub.getValue(),nDoc]);
}
}
)
}
public addByName(str:string) {
this.add({name: str, _id: undefined});
}
}
当使用非空持久存储路由到我的组件时,我得到以下控制台日志(对应于组件的 OnInit 方法中的日志记录):
got value > [] (wiki.component.ts:20)
got value > [Object, Object, Object, Object] (wiki.component.ts:20)
但是我的 DOM 保持不变:
<wiki>
<p>[]</p>
<ul>
<!--template bindings={
"ng-reflect-ng-for-of": ""
}-->
</ul>
<input>
<button>ADD</button>
</wiki>
因此,手动订阅我的 observable 确实有效并为我获取了值。但是异步管道没有得到它们。
我是不是做错了什么,或者这是一个错误?
编辑
2016 年 12 月 19 日下午 3:45
The
ngFor
directive was "let item of items | async" before, and I thought maybe the async pipe was scoped to the item and not my observable so I added brackets, but results were unchanged. This is not relevant for the issue.
2016 年 12 月 20 日下午 3 点 06 分
按照@olsn 的建议,使用自动日志初始化组件的 items
属性,以检查模板是否订阅了 Observable。
确实如此。所以归结为检测变化,我猜。修改标题。
添加这些信息:我的组件现在是这样的(评论更改)
@Component({
selector: 'wiki',
templateUrl: './wiki.component.html',
changeDetection: ChangeDetectionStrategy.OnPush // <=== I've read this might help. It doesn't.
})
export class WikiComponent implements OnInit {
items: Observable<WikiItem[]> = this._db.items //
.do(x => console.log("got value", x)) // <== new initialization, with a stream
.publishReplay().refCount(); //
constructor(private _db : WikiDbService, private _cd: ChangeDetectorRef) { }
ngOnInit() {
// <=== moved items initialization
}
reload() : void {
this._cd.markForCheck(); // <== added a button to force the change detector to react. Does not do anything.
}
}
在模板中加上这个:
<button (click)="reload()">REFRESH</button>
@osln 给出了正确的答案。
问题根本不在于订阅或检测更改,这是因为我的 sub.next
调用是在给外部库的回调中,这具体意味着我是在 Angular 之外进行的领土。
用 NgZone 调用迫使他们回到 Angular 土壤是解决这个问题的方法。
感谢@osln。
最佳答案
尝试在 ngInit 之前初始化您的项目对象,并直接将临时日志添加到流中,这样您就知道模板是否真的订阅了流,因为您当前的日志是在完全独立的流。
@Component({
selector: 'wiki',
templateUrl: './wiki.component.html'
})
export class WikiComponent implements OnInit {
items: Observable<WikiItem[]> = this._db.items
.do(x => console.log("got value", x)
// if items is not a Behavior- or ReplaySubject or ReplayObservable, also add the following:
.publishReplay()
.refCount();
constructor(private _db : WikiDbService) { }
ngOnInit() {
// ..nothing to do here
}
}
此外,您可能会尝试将数据检索包装在 NgZone.run
中:
首先将其注入(inject)您的 DbService:private ngZone: NgZone
(来自 @angular/core
),然后不只是使用 this.sub.next(文档);
,使用:
this.ngZone.run(() => this.sub.next(docs));
(也用于添加调用)
关于Angular 2 变化检测与 observables,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41224671/
我正在尝试在项目中学习和添加 Angular 国际化。我只能理解 Angular 文档 (https://angular.io/guide/i18n-overview) 的编译时翻译。 我需要这样的东
在我的 Angular 应用程序中,基于登录用户,我想通过显示/隐藏不同的菜单项或允许/禁止某些路由来授予或限制功能。 目前成功登录后,我的 .NET Core API 会返回一个 JWT token
我是 Angular 的新手,目前我已经看过 angular.io 网站提供的一些示例。但是在component decorator在文档中的解释,它指出 Angular components are
这里是service employee-service.service.ts的代码 import { Injectable } from '@angular/core'; import { HttpC
我目前正在使用@angular/http URLSearchParams 类来检索 URL 参数。在 Angular 5 中,注意到这已被弃用,但我没有看到以我当前使用的方式替换 URLSearchP
我目前正在使用@angular/http URLSearchParams 类来检索 URL 参数。在 Angular 5 中,注意到这已被弃用,但我没有看到以我当前使用的方式替换 URLSearchP
如何正确安装 PUG/JADE 到 Angular 2 或更高版本 这样在工作和 AOT 和 JiT 的同时 工作单元和集成测试 并且在创建每个新组件时不会受到太多影响 最佳答案 我看到了很多解决方案
我的 Angular 12 应用程序中有一些通用组件,我计划将其创建为一个 Angular 库,以便其他应用程序也可以使用它。我们有一些应用程序在较低版本的 angular(例如 angular 8/
tl;dr; ng build 删除了包含我编译的自定义库的/dist 文件夹。这会使我项目代码中对该库的所有引用无效,从而导致 ng build 最终失败。我做错了什么? 我关注了documenta
我正在将一些“遗留”(非 typescript )js 库导入到我的 Angular SPA 中。 通常我只是从 cdn 添加一个负载到 index.html 就像: 在 Angular 分量中我只
我有这个 angular 应用程序,它基本上使用了库的概念。 我有 2 个名为 的库Lib1 和 lib2 根据他们所服务的微服务分组。 现在我将这些库导入主应用程序,即 应用1 事情一直到现在。 现
我在我的项目中启用了 angular Universal。我现在想完全删除它。我试图删除以下文件 /server.ts /webpack.server.config.js /src/tsconfig.
我已经有一个 AuthService 在登录时对用户进行身份验证,并且 AuthGuard 在未登录的情况下阻止访问。 某些页面我通过 UserProfile/Role 限制访问,但现在我需要阻止页面
我正在尝试使用 angular、TypeORM、SQLite 和其他组件作为 webpack 构建 Electron 应用程序。 我从在 GitHub 上找到的示例开始我的开发:https://git
我在从 Angular 8 更新到 9 并运行时遇到以下错误 ng 更新@angular/material: Package "@angular/flex-layout" has an incompa
我正在尝试使用 Angular 9,我想创建一个项目,然后创建一个库项目并开始向其中添加我想稍后在 GitHub 上发布的通用模块,并在我的本地使用这些库项目。 相关依赖如下: Angular CLI
我正在尝试使用 Angular 9,我想创建一个项目,然后创建一个库项目并开始向其中添加我想稍后在 GitHub 上发布的通用模块,并在我的本地使用这些库项目。 相关依赖如下: Angular CLI
我正在我的 h1 元素“之前”创建一个小的程式化三 Angular 形图案,但我无法正确地圆 Angular 。右上角没问题,但其他两个有剪裁问题。 这是输出以及形状的放大图像: 使用的代码如下: h
我有一个 Angular 元素,带有自定义标记名 - fancy-button。如何将 fancy-button 嵌入 Angular 应用程序? 我已经尝试了以下方法,但都没有用 - 在 index
我已将我的项目从 angular 5.2.9 升级到 angular 6.0.0-rc.5。 除了包路径中的几个快速 RxJS 修复外,一切看起来都不错。(此链接非常有用:Want to upgrad
我是一名优秀的程序员,十分优秀!