これは私の最初の投稿ですので、何かが間違っていたり、適切な場所にない場合は、教えてください。私の質問に今collectionCountがサービスのテンプレート/ meteor-rxjsに値を表示していません
:
私はthe Angular2 meteor-base boilerplateに基づいて簡単なのto-doアプリケーション内でサービスを実装しようとしています。
- 表示に-Doリストの束(これは作品<):
は、私は二つのことをやろうとしている次のコードは、考えてみましょう
0: - .collectionCount()
todolist.service.ts(<これは動作しません)
import { Injectable } from '@angular/core'; import { Subscription, Observable } from 'rxjs'; import { MeteorObservable, ObservableCursor } from 'meteor-rxjs'; import { Todolist } from '../../../../../both/models/todolist.model'; import { Todolists } from '../../../../../both/collections/todolists.collection'; @Injectable() export class TodolistService { todolistSubscription: Subscription; todoLists$: Observable<Todolist[]>; numLists$: Observable<number>; constructor() { this.initListSubscription(); } initListSubscription() { if (!this.todolistSubscription) { this.todolistSubscription = MeteorObservable.subscribe("todolists").subscribe(() => { // Code to be executed when the subscription is ready goes here // This one works this.todoLists$ = Todolists.find({}).zone(); this.todoLists$.subscribe((lists) => { console.log(lists); }); // This one doesn't this.numLists$ = Todolists.find({}).collectionCount(); this.numLists$.subscribe((numberOfLists) => { console.log(numberOfLists); }) }); } } getLists(selector?, options?) { // Just in case anyone is wondering what those params are for... // return Todolists.find(selector || {}, options || {}); return this.todoLists$; } getListsCount() { return this.numLists$; } unsubscribeFromLists() { this.todolistSubscription.unsubscribe(); } }
この1つは、私は私のapp.module.tsにインポートして、プロバイダアレイに追加します。
import { Component, OnInit } from '@angular/core';
import { TodolistService } from '../../shared/todolist.service'
// + all other relevant imports, e.g. Todolist (the model), Todolists (collection)
@Component({
selector: 'list-component',
template,
styles: [style]
})
export class ListComponent implements OnInit{
lists$: Observable<Todolist[]>;
numLists$: Observable<number>;
constructor(private _todolistService: TodolistService){}
ngOnInit(){
// Again, this one works...
this._todolistService.getLists().subscribe((lists) => {
console.log(lists);
});
// ...and this does not
this._todolistService.getListsCount().subscribe((number) => {
console.log(number);
});
// This I can also use in my template, see below...
this.lists$ = this._todolistService.getLists();
// This one I can't
this.numLists$ = this._todolistService.getListsCount();
}
}
todolist.component.html:例えば、私は次の手順に従ってください私のテンプレートで
私list.component.ts私はそうのようなサービスを利用で次に
、 :
<!-- This one works... -->
<div *ngFor="let list of lists$ | async">{{list._id}}</div>
<!-- This one doesn't... -->
<span class="badge">{{ numLists$ | async }}</span>
物事は私が試した: .zoneを添加
- () -
getListsCount() {
return this.numLists$.zone();
}
- ような私のサービスに規定された方法オペレータは、)(.zoneの添加であること(これを試みました - initListSubscription()でオペレータ) - サブスクリプションが
- は私のコンポーネントで同じことをしようとした準備ができたとき、私は物事を行うサービスの方法、私は呼ん
// with the addition of .zone()
this.numLists$ = this._todolistService.getListsCount().zone();
.zoneを追加=====
()は趣味としてこれを行い、誰か、行うには明白なこととして、私の視点から、でした。残念ながら、何の効果もありません。私が理解から、これはangularsゾーンに起こっasynchronusタスクを添付して、基本的には例えば
constructor(private _zone: NgZone){}
ngOnInit(){
this._zone.run(() => {
//...do stuff here that's supposed to be executed in angulars zone
})
}
を言うと同じです。
誰かが私を助けることができますか?私は実際に何が起こっているのかを理解しようとしましたが、私は頭を包むことができません。なぜ、私はその観察可能なリストの実際の数を得ることができません。私は、直接私のコンポーネントでこのすべてを行うことをしたと-DOSに、私は思います私は新しい追加した場合、私は私のリストを自動的に更新したい場合は
:
私は思ったんだけどもう一つは
MeteorObservable.subscribe("todolists").subscribe(() => {
// The additional part that's to be executed, each time my data has changed
MeteorObservable.autorun().subscribe(() => {
this.lists$ = Todolists.find({}).zone();
// with/without .zone() has the same result - that being no result ...
this.listCount$ = Todolists.find({}).collectionCount();
});
});
ここでは、私のサービス内からどのように反応性を達成するかについての私の頭を覆すことはできません。私はこれを試して、もう一度やりたいリストのために働いていますが、.collectionCount()ではそうではありません。
ここで正しい方向を指すことができるかどうか本当に感謝します。たぶん私は何かが欠けているかもしれませんが、私はリストを表示することができます(そして、コンポーネント内から何かを実行すると反応的に更新することもできます)ので、理論的にはうまくいくはずです。
ありがとうございます!
UPDATE:私は最終的に実用的なソリューションを取得するために管理@ghybsから
感謝。下に、最終的なコードがあります。
todolist.service.ts:
import { Injectable } from '@angular/core';
import { Observable, Subscription, Subject } from 'rxjs';
import { MeteorObservable, ObservableCursor } from 'meteor-rxjs';
import { Todolist, Task } from '../../../../../both/models/todolist.model';
import { Todolists } from '../../../../../both/collections/todolists.collection';
@Injectable()
export class TodolistService {
todolistSubscription: Subscription;
todoLists$: ObservableCursor<Todolist> = Todolists.find({});
numLists$: Observable<number>;
numLists: number = 0;
subReady: Subject<boolean> = new Subject<boolean>();
init(): void {
if(!this.todolistSubscription){
this.subReady.startWith(false);
this.todolistSubscription = MeteorObservable.subscribe("todolists").subscribe(() => {
this.todoLists$ = Todolists.find({});
this.numLists$ = this.todoLists$.collectionCount();
this.numLists$.subscribe((numberOfLists) => {
console.log(numberOfLists)
});
this.todoLists$.subscribe(() => {
this.subReady.next(true);
});
});
}
}
isSubscriptionReady(): Subject<boolean> {
return this.subReady;
}
getLists(selector?, options?): ObservableCursor<Todolist> {
return this.todoLists$;
}
getListsCount(): Observable<number> {
return this.numLists$;
}
addList(name: string, description: string): Observable<string> {
return MeteorObservable.call<string>("addTodoList", name, description);
}
addTask(listId: string, identifier: string, description: string, priority: number, start: Date, end: Date): Observable<number> {
return MeteorObservable.call<number>("addTask", listId, identifier, description, priority, start, end);
}
markTask(listId: string, task: Task, index: number) : Observable<number> {
return MeteorObservable.call<number>("markTask", listId, task, index);
}
disposeSubscription() : void {
if (this.todolistSubscription) {
this.subReady.next(false);
this.todolistSubscription.unsubscribe();
this.todolistSubscription = null;
}
}
}
dashboard.component.ts:
import { Component, OnInit, OnDestroy } from '@angular/core';
import { Router } from '@angular/router';
import { routerTransition } from '../shared/animations'
import { Observable, Subject } from 'rxjs';
import { ObservableCursor } from 'meteor-rxjs';
import { Todolist } from '../../../../both/models/todolist.model';
import { TodolistService } from '../shared/services/todolist.service';
import template from './dashboard.component.html';
import style from './dashboard.component.scss';
@Component({
selector: 'dashboard',
template,
styles: [style],
animations: [routerTransition()]
})
export class DashboardComponent implements OnInit, OnDestroy {
todoLists$: ObservableCursor<Todolist>;
numTodoLists$: Observable<number>;
numTodoLists: number = 0;
constructor(private _router: Router, private todolistService: TodolistService) {}
ngOnInit() {
this.todolistService.init();
this.todolistService.isSubscriptionReady().subscribe((isReady) => {
if(isReady){
this.todolistService.getListsCount().subscribe((numTodoLists) => {
this.numTodoLists = numTodoLists;
});
}
});
}
sideNavShown: boolean = true;
toggleSideNav() {
this.sideNavShown = !this.sideNavShown;
}
ngOnDestroy() {
this.todolistService.disposeSubscription();
}
}
dashboard.component.html:
に加入した後にサービスから復帰し、受信e値は、私は変数に値を代入し、そのようにそれを使用します。
になり
<span class="badge badge-accent pull-right">{{ numTodoLists }}</span>
は、値が自動的にすぐに私は新しいを追加すると、更新され、リスト - すべて期待どおりに動作します。
ありがとうございます。特に@ghybs、あなたは素晴らしいです。
私が見た最初の質問 – chazsolo
@chazsoloありがとう!興味があれば、私のために働いているソリューションで質問を更新しました。 – minau87