【问题标题】:how to access objects gotten from service in the component?如何访问从组件中的服务获取的对象?
【发布时间】:2017-04-02 11:36:55
【问题描述】:

当我尝试在 searchAtoms 中使用“this.atoms”访问原子时,它返回“TypeError: Cannot read property 'length' of undefined”。我认为原子都设置好了,因为 *ngFor 运行良好。订阅背后有一些隐藏的逻辑?如果有人知道这件事,你能提供一些线索吗?而且,还有另一个问题,当我使用参数定义 getAtoms 方法时,从 atom.service.ts 中的输入字段获取的原子名称值,例如 this.service.getAtoms(newAtom)。但是我得到“只有在构造函数实现中才允许使用参数属性”。我想我不能用这种方式。有人可以为此推荐一种理想的方法吗?

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;
    });
  }
}

【问题讨论】:

    标签: angular service typeerror


    【解决方案1】:

    Http 服务返回一个Observable 并且您订阅它。这是一个异步操作,但您正试图在数据从服务器到达之前访问它。如果您将 console.log 移动到 subscribe 回调中,它将起作用。

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

    对于第二个问题,您只需删除 private 关键字即可。

    getAtoms(newAtom: string) { }
    

    【讨论】:

    • 附加问题,:) 无论如何我可以调用订阅内的方法吗?我通过将 console.log(this.atoms.length) 定义为另一个名为 printTest() 的方法来测试它。我无法调用 printTest,它说“ReferenceError:printTest() 未定义”。我认为这很有意义。最终,我想对这些原子进行分页,所以我需要对原子数组进行一些操作。实际上,我正在考虑通过将其委托给分页服务(paging.service.ts)来切割有限数量的原子。你对这个任务有什么建议吗?我真的很感激。
    • 你叫它像this.printTest()吗?它应该工作。但是,是的,我建议您将分页逻辑移至服务。
    • :) 运行良好。我真的很抱歉,但是如果用户点击查看其他页面,而不是通过订阅获得 Observable 后的数据,我想我必须有重复的原子,不是吗?转念一想,我有些迷茫了。如果可以的话,我会期待你的答复。如果不是,我会多学习。非常感谢。
    • 我认为这超出了这个问题的范围,因为有不同的方法来构建组件和路由;而且我不知道您对重复原子的确切含义。所以你可以接受这个答案,尝试自己解决其他问题,如果没有发布新问题。 ;)
    • 是的,我想是的。非常感谢您的友好解释!
    猜你喜欢
    • 2019-08-26
    • 1970-01-01
    • 2015-07-23
    • 2017-03-08
    • 2020-10-12
    • 1970-01-01
    • 1970-01-01
    • 2023-03-16
    • 2010-10-24
    相关资源
    最近更新 更多