第二次编辑:
原来如此!我已经找到了问题,但为了理解这个问题,你必须先了解目标:
我目前正在开发一个Angular Chrome-Extension
,它有一个持久的后台脚本(与我发现的所有示例和教程不同,它只解释非持久性后台脚本 - 或事件页面Example)。
后台脚本实际上是一个Angular组件,它包含logic service
,可以在不同的chrome组件(弹出窗口,选项等等)中访问。
window
对象,它导致有2个应用程序实例,1个位于“后台窗口”,另一个位于“弹出窗口”中。chrome.extension.getBackgroundPage()
获取弹出窗口中的服务时,我得到了正确的实例,但现在出现了另一个问题,后台服务中的更改未反映,因为该服务不在Angular的应用程序上下文中。 / LI>
醇>
所以我有一个新问题:
是否有可能告诉Angular“添加/观察”未实例化的Angular服务并将其添加到应用程序上下文中?
编辑: 我已经添加了2个服务,看起来我的项目中存在更深层次的问题,因为这个演示代码按预期工作..将在解决时继续更新。
原始问题
我正在尝试将异步数据从父组件传递到子组件&我遇到了一些问题。
该服务拥有一个可观察的&父订阅它+通过async
管道传递给孩子的输入。
问题是父母选择了改变(仅来自控制器)&没有任何UI更新。
我可以在订阅函数中触发ChangeDetectorRef.detectChanges()
,但在我看来,这似乎是一件非常奇怪的事情,因为async
管道应该已经接受了这些更改,但事实并非如此。
有什么建议吗?
考虑以下代码(这可以像预期的那样起作为新项目):
父组件:
@Component({
selector: 'parent',
template: '<div>
<button (click)="logic.doAction()">Get data</button>
<child [someInput]="logic.data$ | async"></child>
<div>data: {{logic.data$ | async | json}}</div>
</div>'
})
export class ParentComponent {
constructor(public logic: LogicService) {}
}
子组件:
@Component({
selector: 'child',
template: '<span>{{someInput}}</child>'
})
export class ChildComponent {
@Input() someInput: string;
constructor() {}
}
逻辑服务:
@Injectable()
export class LogicService {
private readonly dataSubject: BehaviorSubject<Array<string>>;
private readonly _data$: Observable<Array<string>>;
constructor(private api: ApiService) {
this.dataSubject = new BehaviorSubject([]);
this._data$ = this.dataSubject.asObservable();
}
doAction(): void {
this.api.fetchFromAPI().then((data) => this.dataSubject.next(data));
}
get data$(): Observable<Array<string>> {
return this._data$;
}
}
API服务:
@Injectable()
export class ApiService {
fetchFromAPI(): Promise<Array<string>> {
return new Promise((res, rej) => {
setInterval(() => {
res(['some', 'demo', 'data']);
}, 4000);
});
}
}
答案 0 :(得分:1)
所以我创建了一个指令,在更新observable时强制进行视图更新。
@Directive({
selector: '[detectChanges]'
})
export class DetectChangesDirective implements OnInit, OnDestroy {
private subscription: Subscription;
@Input('detectChanges') observable$: Observable<any>;
constructor(private cd: ChangeDetectorRef) {
}
ngOnInit() {
this.subscription = this.observable$.subscribe((() => {
this.cd.detectChanges();
}));
}
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
使用它非常简单,只需将其应用于您遇到更新问题的视图:
<div [detectChanges]="logic.data$">
<button (click)="logic.doAction()">Get data</button>
<child [someInput]="logic.dataValue"></child>
<div>data: {{logic.dataValue | json}}</div>
</div>
重要提示:
async
管道&amp;相反,我将实际值传递给我绑定它的位置。Observable
传递给指令,该指令会在值更改时跟踪答案 1 :(得分:0)
IMO,如果服务方法返回一个observable,它应该在需要数据的地方解包(订阅)。我会这样做:
<child [someInput]="service.observable"></child>
在孩子身上:
export class ChildComponent {
@Input() someInput: Observable;
// subscribe to someInput in the child
}