2017-01-21 14 views
0

私はonInit処理を行い、一部のDBデータが呼び出されてから結合されます。私はそれが正しくフォーマットされていないので、ここに私の方法全体を貼り付けることができません。Angular2と配列フィルター/ find

u.skills.forEach(s => { 
    let skillEntry: SkillEntry = new SkillEntry(); 
    skillEntry.skill = s; 

    let sbs: SkillBase[] = this.cachedSkillBases.filter(sb => sb.id == s.skillBaseId); 
    if (sbs.length>0) { 
     skillEntry.skillBase = sbs[0]; 
    } else { 
     console.log('not found'); 
     this._userService.getSkillBase(s.skillBaseId).toPromise() 
     .then(res => { 
      skillEntry.skillBase = res; 
      this.cachedSkillBases.push(res); 
     }); 
    } 
}); 

ここでは、一時キャッシュを実装して高速化していますが、検索は機能しません。変数「s」の場合、このフィルタが動作しない理由を具体的に私は知りませんが存在し、常に適切なID

let sbs: SkillBase[] = this.cachedSkillBases.filter(sb => sb.id == s.skillBaseId); 

を持って、それは私がここで行方不明です何ですか?

+0

skillBaseId)は(新しい上で自動的に設定されていますか? – misha130

+0

あなたの '=='を '==='に変更するだけです。違いが生じる・異なる? –

+0

skillBaseIdは、以前に取得されたデータベースに由来します。常に存在し、ここでは特に問題にはなりません。そうしないと、次に発生するサービスコールも失敗します。 ===助けにもならない。 – smoczyna

答えて

0

キャッシュ実装は非同期です。つまり、ループ中に100%のキャッシュミスと複数の重複要求が発生します。 Promise thenは、非同期または一部の時間で実行されます

+0

私は約束をしていないし、私のキャッシュを呼び出します。コンポーネントと共に初期化され、決してクリアされません。それはマークされた行だけでアクセスされ、非同期ではありません。あなたは詳細を教えていただけますか? – smoczyna

+0

これ以外の場合はhttpを呼び出していますが、forEachループの後にすべての呼び出しが完了します。 console.logを関連する場所に追加するだけで、どのように動作するかがわかります。 – kemsky

+0

でも問題はありませんが、2回目の実行でエントリが見つからない理由は何ですか?最初の呼び出し後、キャッシュは完全に読み込まれ、ページリフレッシュはhttpコールを引き起こさないはずですが、それは実行されます。また、コンソールは、ループの前にキャッシュ内にあるすべてのエントリを表示します。 – smoczyna

0

すべての権利は、ここに私の完全な方法です。最初の実行ではデータが利用できないのですが、それ以降はローカルキャッシュが機能しないのは分かりますが、空であるかのように見えますか? 残念ながら、このページでは拒否されているため、一度にすべてのメソッドを貼り付けることができません(正しくフォーマットされていません)。上の例では、メソッドの宣言だけがあり、キャッシュ配列はコンポーネントレベルで宣言されています。

**プライベートgetUsers(){***

let fetchedUsers: User[];
 
let userEntries: UserEntry[] = []; 
let skillEntries: SkillEntry[]; 

this._userService.getAllUsers(this.searchForm.userName, this.searchForm.skillName, this.searchForm.groupName)
 
    .toPromise()
 
    .then(result => { 
    fetchedUsers = result; 
    fetchedUsers.forEach(u => { 
     let userEntry: UserEntry = new UserEntry(); 
     userEntry.detail = u; 

     skillEntries = []; 
     u.skills.forEach(s => { 
     let skillEntry: SkillEntry = new SkillEntry(); 
     skillEntry.skill = s; 

     let sbs: SkillBase; 
     Promise.all(this.cachedSkillBases).then(res => { 
      sbs = res.find(sb => sb.id == s.skillBaseId); 
     }); 

     if (sbs) { 
      skillEntry.skillBase = sbs; 
     } else { 
      this._userService.getSkillBase(s.skillBaseId).toPromise() 
      .then(res => { 
       console.log('got skills'); 
       skillEntry.skillBase = res; 
       this.cachedSkillBases.push(res); 
      }); 
     } 

     if (s.skillDetailId) { 
      let sds: SkillDetail; 
      Promise.all(this.cachedSkillProficiencies).then(res => { 
      sds = res.find(sd => sd.id == s.skillDetailId); 
      }); 
      if (sds) { 
      skillEntry.skillProficiency = sds; 
      } else { 
      this._userService.getSkillProficiency(s.skillDetailId).toPromise() 
       .then(res => { 
       console.log('got proficiencies'); 
       skillEntry.skillProficiency = res; 
       this.cachedSkillProficiencies.push(res); 
       }); 
      } 
     } 
     skillEntries.push(skillEntry); 
     }); 
     console.log('setting users'); 
     userEntry.skills = skillEntries; 
     userEntries.push(userEntry); 
    }) 
    }) 
    .then(res => this.users = userEntries); 
+0

もう1つの解決策は、他のものがすべて完了したときにユーザーを返すようにこのコードを作成することです。コンソールの最初のメッセージではなくconsole.log( 'ユーザー設定')メッセージが最後に表示されます今。このようにして、私は働かないキャッシュを取り除くことができます。 – smoczyna

関連する問題