2016-05-23 11 views
2

MeteorにAngular 2を使用すると、サービスを使用してコンポーネント間でデータを渡し、フェッチして保存するコンポーネントツリーがあります。サービスにおいてObservable SubscriptionからAngular 2コンポーネントが更新されていません

constructor() { 
    this._contactId = new Subject<string>(); 
    this.contactid$ = this._contactId.asObservable(); 

    } 
    // Service message commands 
    SetContactId(id: string) { 
     console.log("SetContactId "+id); 
     this._contactId.next(id); 
    } 

これは、新しい連絡先または既存の編集を区別するためにコンポーネントに使用されます。

<div style="display:flex"> 
    Id: {{contactid}} 
    <div style="flex:1 order:1" *ngIf="!contactid"> 
     <contact-new></contact-new> 
    </div> 
    <div style="flex:1 order:1" *ngIf="contactid"> 
     <contact-editor ></contact-editor> 
    </div> 
</div> 

ここにコンポーネントのサブスクリプションがあります。

private contactid : string; 

constructor (private _ContactService:ContactService) { 


    ContactService.contactid$.subscribe(
     id => { 
      //this.id = id; 
      console.log('ContactEdit subscription '+id); 
      this.contactid = id; 
      this.updateId(id); 
     }); 
    } 

    updateId(id) { 
     console.log('updateid '+id) 
     console.log(this.contactid); 
    } 

contactidは2つの方法で設定され、結果は同じではありません。

clickItem(contact) { 
     console.log('clickItem'); 
     console.log(contact._id); 
     this._contactService.SetContactId(contact._id); 
    } 

これは、連絡先のリストとクリックハンドラを持つコンポーネントからのものです。それはサービスのIDを設定し、新しい/編集コンポーネントは期待通りに機能します。第二の方法は、新しい連絡先コンポーネントコンストラクタである

this.newContactForm.valueChanges 
      .debounceTime(1000) 
      .subscribe(newValue => this.readySave()) 

readySave() { 
... 
this._ContactService.newContact(q,true); 
} 

次のようにnewContact方法があり、これが呼び出されたときにコンポーネントがcontactidを更新しません。

newContact(data,setid : boolean) { 
    let self = this; 
    this.call('contacts.add',data,function (error,id) { 
     if (!error) { 
      console.log(id); 
     if (setid) { 
      self.SetContactId(id); 
      } 
      //self.loadRelations(id); 
     } 
     }); 
    } 

クリックハンドラは機能しますが、コレクションの挿入から戻ってからの遅延は、もう一方のシナリオの更新に失敗するようです。タブをクリックするか、入力をクリックすると、コンポーネントが更新されます。 Console.logの呼び出しは、IDが正しく渡されて設定されていることを示します。

提案がありますか?

編集: 関連するコンポーネントだけで、アプリケーションのスケルトンを構築しました。奇妙なことに、最初のカップルのレコードを処理し、ドキュメントを挿入した後に更新せず、コールバックにidを取得してから、コンポーネントのcontactidを割り当てるsubscribe関数に渡します。

もう1つ編集:この問題を少しでも克服した後、私は問題がどこに存在するかを解明したと思いますが、解決策はありません。

サービスはMeteorComponent、Injectable()です。コンポーネントにはAngular2-meteorが付属し、subscribeメソッドとcall meteorメソッドをラップします。具体的には、関数呼び出しが関数を実行してサーバー上の値を返すと値を更新する約束を返すようです。

SetContactIdがクリックハンドラから呼び出されても、MeteorComponent内のMeteorメソッド 'call'コールバック関数によって呼び出された場合は更新されません。

解決策を見つける。

+0

問題の原因はわかりません。この問題を示すPlunkerを作成できますか? –

+0

contactid変数は、テンプレート内で反応的に更新されません。 –

+0

'console.log( 'ContactEditサブスクリプション' + id);'と 'updateId(id){...} 'コンソールに印刷しますか? –

答えて

3

Hongbo_Miaoのおかげで、私は答えを見つけました。 SetContactIdコールをNgZoneのMeteor.callコールバックにラップして更新する必要があります。それは期待どおりに動作します。

newContact(data,setid : boolean) { 
    this.call('contacts.add',data, 
     (error,id) => { 
      this._ngZone.run(() => { 
       console.log(id); 
       if (setid) { 
        this.SetContactId(id); 
        console.log('newContact callback'); 
       } 
      }); 
     }); 
    } 
+0

'autorun'メソッドはNgZoneの中で実行する場合、何らかの理由でbooleanフラグを持ちますが、' call'は何もしません。私はこれに一度も噛まれた。おそらくバグレポートの価値がありますか? –

+0

ハ、私は助けてうれしい! –

関連する問題