我是面向对象编程的新手,并且我认为对于经验丰富的OO程序员来说这应该是一个简单的概念,但我当然正在努力解决它。
在我的Angular2应用程序中,我有一个HttpService类,如下所示:
http.service.ts
@Injectable()
export class HttpService {
constructor(private http: Http) { }
addLeaf(parentId, label, name){
var headers = new Headers();
headers.append('Content-Type', 'application/json');
return this.http.post('http://localhost:8000/addleaf/',
{'parentId':parentId,'label':label, 'name':name},
{ headers: headers })
.map(res => res).subscribe();
}
我尝试从另一个类中调用此方法,如下所示:
leaf.ts
import { HttpService } from './http.service';
export class Leaf{
name: string;
...
http: Http; // very unsure about these two lines
private httpService: HttpService = new HttpService(this.http)
constructor(input){
this.name = input.name;
...
add(){
//what should go here?
this.httpservice.addLeaf(this.id, this.label, this.name);
//error -> cannot read property 'post' of undefined
}
阅读this,我尝试创建HttpService类的实例,但是我得到了post函数不存在的错误。也没有把httpService放在构造函数中。
我在我的html中调用这个方法:
(click)="leaf.add()"
编辑:关注@ peeskillet的回答我修改了leaf.ts并添加了leaf.component.ts,如下所示:
leaf.ts
export class Leaf{
name: string;
...
constructor(input){
this.name = input.name;
...
add(){
//what should go here?
}
}
leaf.component.ts
@Component({
providers: [HttpService],
})
export class LeafComponent {
leaf: Leaf;
constructor(private httpService: HttpService) {
this.httpService.addLeaf(this.leaf.id, this.leaf.type, this.leaf.name)
}
}
如果我用预定义的字符串代替params,服务工作正常,但仍然不确定如何将点击的叶子的参数传递给它。
答案 0 :(得分:1)
使用Angular,我们使用dependency injection和Inversion of Control。这意味着我们不是自己创建服务,而是让Angular创建它。然后我们只是询问服务,然后Angular将解析服务所具有的任何依赖项。举个例子
@Injectable()
class Service {
constructor(private http: Http) {}
}
此处,Service
在Http
中具有依赖关系。 Http
不是我们可以凭空攫取的东西。我们不能做到
let service = new Service(new Http());
Http
也依赖于其他一些服务。这是它的构造函数的样子
class Http {
constructor(backend: ConnectionBackend, options: RequestOptions) {}
}
你可能认为也许你可以用ConnectionBackend
和RequestOptions
new Http(new ConnectionBackend(), new RequestOptions())`
但你也不能这样做,因为ConnectionBackend
也需要依赖。因此我们使用Inversion of Control。我们只是将服务添加到容器中,当要求提供服务时,Angular会查找服务,因为它需要Http
,并且看到Http
需要ConnectionBackend
和{ {1}}等,Angular将创建所有项目,在其注册表中查找所有这些项目并将它们全部放在一起,如Voltron。然后它将为我们提供完全填充的服务。
所以我们将服务添加到容器中,我们首先需要在服务上添加RequestOptions
装饰器
Injectable
然后我们需要将其添加到@Injectable()
class Service {
constructor(private http: Http) {}
}
@NgModule.providers
现在,只要我们要求@NgModule({
imports: [ HttpModule ],
providers: [ Service ]
})
class AppModule {}
,就会使用Service
完全填充Http
。
我们如何通过另一个服务或组件(指令,管道等)的构造函数来请求服务
HttpModule
通过将@Component({
})
class MyComponent {
constructor(private service: Service) {}
}
类型视为构造函数参数,Angular知道在其容器中查找Service
,然后将其传递给我们。这是依赖注入和控制反转的基础。
以Service
为例。如果是一个服务,那么你可以做同样的
Leaf
如果您不想添加@Injectable()
class Leaf {
constructor(private service: Service) {}
}
@NgModule({
imports: [ HttpModule ],
providers: [ Leaf, Service ]
})
class AppModule {}
作为提供商,则不需要。只是做
Leaf