2016-11-18 10 views
0

searchAtomsで 'this.atoms'を使用してアトムにアクセスしようとすると、「TypeError:プロパティ '長さ'が未定義です」が返されます。 * ngForがうまく働いているため、原子がすべて設定されていると思っています。サブスクリプションの背後に隠れたロジックがいくつかありますか?誰かがこれについて知っているなら、あなたは手がかりを与えることができますか?また、別の質問として、パラメータを持つgetAtomsメソッドを定義したとき、atom.service.tsの入力フィールドからthis.service.getAtoms(newAtom)のように取得されたatom nameの値を定義しました。しかし、私は "パラメータのプロパティは、コンストラクタの実装でのみ許可されています"を取得します。私はこの方法では使えないと思う。誰かがこれに望ましい方法をお勧めしますか?コンポーネントのサービスから取得したオブジェクトにアクセスする方法は?

app.component.ts

import {Component} from 'angular2/core'; 
import {Router} from 'angular2/router'; 
import {AtomService} from './service/atom.service'; 
import {Atom} from './datatype/Atom'; 

@Component({ 
    selector: 'my-app', 
    template: `<br> 
    <input #atomname value='atom1'> 
    <button (click)=searchAtoms(atomname.value)>Search Atoms</button> 
    <br><br> 
    <ul> 
     <li *ngFor="#atom of atoms"> 
      {{atom.id}} - {{atom.name}} 
     </li> 
    </ul>`, 
    providers: [ConceptService] 
}) 


export class AppComponent { 

    atoms: Array<Atom>; 

    constructor(private service : AtomService) { 

    } 

    searchAtoms(newAtom: string) { 
     console.log("searchAtoms\t" + newAtom); 
     if (newAtom) { 
      this.service.getAtoms(newAtom).subscribe(data => this.atoms = data); 
      console.log(this.atoms.length); 
     } 
    } 
} 

atom.service.ts

import { Injectable }  from 'angular2/core'; 
import { Http, Response, URLSearchParams, Headers } from 'angular2/http'; 
import 'rxjs/add/operator/map'; 
import {Atom} from '../datatype/Atom'; 

@Injectable() 
export class ConceptService { 

    constructor(private http: Http) { 
    this.http = http; 
    } 

    getAtoms(private newAtom: string) { 
    return this.http.get('api/atoms.js') 
    .map((responseData) => {return responseData.json()}) 
    .map(data => { 
     let results:Array<Atom> = []; 
     for (var i = 0; i < data.result.length; i++) { 
      results.push(new Atom(data.result[i].id, data.result[i].name)); 
     } 
     return results; 
    }); 
    } 
} 

答えて

2

HttpサービスはObservableを返し、あなたはそれを購読します。これは非同期操作ですが、サーバーから到着する前にデータにアクセスしようとしています。 subscribeコールバックの中にconsole.logを移動すると正常に機能します。

this.service.getAtoms(newAtom).subscribe(data => { 
    this.atoms = data; 
    console.log(this.atoms.length); 
}); 

2番目の質問では、privateキーワードを削除するだけです。

getAtoms(newAtom: string) { } 
+0

ありがとうございました。うまくいきました。 –

+0

追加の質問、:)とにかく私はサブスクライブの中でメソッドを呼び出すことができますか?私はprintTest()という名前の別のメソッドとしてconsole.log(this.atoms.length)を定義してテストしました。 printTestを呼び出せませんでした。 "ReferenceError:printTest()が定義されていません"と表示されます。私はそれが理にかなっていると思う。最終的には、これらの原子をページめくりたいので、原子配列の操作が必要です。実際には、限られた数の原子をページングサービス(paging.service.ts)に委ねることによってスライスすることを考えています。この仕事のためのいくつかの勧告がありますか?私は本当にそれを再び感謝します。 –

+0

'this.printTest()'のように呼びましたか?それは動作するはずです。しかし、ええ、ページングのロジックをサービスに移すことをお勧めします。 – Puigcerber

関連する問題