gpt4 book ai didi

angular - 创建具有依赖关系的类的新实例,不了解工厂提供者

转载 作者:搜寻专家 更新时间:2023-10-30 21:15:05 25 4
gpt4 key购买 nike

我已经研究这个问题一段时间了,但似乎找不到足够清晰易懂的答案。我有一个 TestComponent,它使用 TestService 从服务器获取一组 TestModel。当我抓取这些测试模型时,它只是一个 json 文件,服务器正在读取并以正确的 mime 类型发回。从服务器获取测试模型后,我将它们放在一个简单的选择元素下拉列表中。选择测试模型后,它会在嵌套组件 TestDetailComponent 中显示所选测试模型。

一切都很好,工作正常。当我从服务器中提取数据时,我总是遇到问题。由于 JavaScript 没有运行时检查,我们无法自动将 JSON 从服务器转换为 typescript 类,因此我需要使用检索到的 JSON 手动创建 TestModel 的新实例。

好的,问题来了。我需要调用新的 TestModel 并为其提供依赖项,但它需要是 TestModel 的新实例。我希望 TestModel 能够将自身保存并更新回服务器,因此它依赖于来自 @angular/core 的 Http,并且它依赖于我创建的配置类,该 Angular 注入(inject)了 opaqueToken,CONFIG.I无法弄清楚如何获取 TestModel 的新实例。这是初始文件

测试组件:

import { Component, OnInit } from '@angular/core';

import { TestService } from './shared/test.service';
import { TestModel } from './shared/test.model';
import { TestDetailComponent } from './test-detail.component';

@Component({
selector: "test-component",
templateUrl: 'app/test/test.component.html',
styleUrls: [],
providers: [TestService],
directives: [TestDetailComponent]
})
export class TestComponent implements OnInit {

tests: TestModel[] = [];
selectedTest: TestModel;

constructor(private testService: TestService) {};

ngOnInit() {
this.testService.getTestsModels().subscribe( (tests) => {
console.log(tests);
this.tests = tests
});
}
}

测试组件模板:

<select [(ngModel)]="selectedTest">
<option *ngFor="let test of tests" [ngValue]="test">{{test.testing}}</option>
</select>
<test-detail *ngIf="selectedTest" [test]="selectedTest"></test-detail>

测试细节组件:

import { Component, Input } from '@angular/core';
import { JsonPipe } from '@angular/common';

import { TestModel } from './shared/test.model';

@Component({
selector: 'test-detail',
templateUrl: 'app/test/test-detail.component.html',
pipes: [JsonPipe]
})
export class TestDetailComponent {
@Input() test;
}

测试细节组件模板

<p style="font-size: 3em;">{{test | json}}</p>

测试模型

import { Injectable, Inject } from '@angular/core';
import { Http, Response, Headers, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Rx';

import { CONFIG } from './../../config/constants';

@Injectable()
export class TestModel {

"testing": number;
"that": string;
"a": string;

constructor(private http: Http, @Inject(CONFIG) private config) {}

save(): Observable<TestModel[]> {

let url = this.config.apiUrl + "test";
let body = JSON.stringify({
testing: this.testing,
this: this.that,
a: this.a
});
let headers = new Headers({'Content-Type': 'application/json'});
let options = new RequestOptions({headers: headers});

return this.http.post(url, body, options)
.map( (response) => response.json() )
.map( (results) => {
results.map( (aggregate, current) => {
aggregate.push(<TestModel>current);
return aggregate;
}, new Array<TestModel>())
}).catch(this.handleError);

}

update() {

let url = this.config.apiUrl + "test";
let body = JSON.stringify({
testing: this.testing,
this: this.that,
a: this.a
});
let headers = new Headers({'Content-Type': 'application/json'});
let options = new RequestOptions({headers: headers});

return this.http.put(url, body, options)
.map( (response) => response.json() )
.map( (results) => {
results.map( (aggregate, current) => {
aggregate.push(<TestModel>current);
return aggregate;
}, new Array<TestModel>())
}).catch(this.handleError);

}

private handleError(err): Observable<any> {

let errMessage = err.message ? err.message : err.status ? `${err.status} - ${err.statusText}` : 'Server Error';

return Observable.throw(new Error(errMessage));

}

}

测试服务

import { Injectable, Inject } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Rx';

import { CONFIG } from './../../config/constants';
import { TestModel } from './test.model';

@Injectable()
export class TestService {

constructor(private http: Http, @Inject(CONFIG) private config) {}

getTestsModels(): Observable<TestModel[]> {

let url = this.config.apiUrl + "test";

return this.http.get(url)
.map( (response) => response.json() )
.map( (results) => {
return results.map( (current) => {
return <TestModel>current; // <<<--- here is the error
})
})
.catch(this.handleError);

}

private handleError(err): Observable<any> {

let errMessage = err.message ? err.message : err.status ? `${err.status} - ${err.statusText}` : 'Server Error';

return Observable.throw(new Error(errMessage));

}

}

我试过使用 ReflectiveInjector,所以 TestService 变成了这样:

    import { Injectable, Inject, ReflectiveInjector } from '@angular/core';
import { Http, Response } from '@angular/http';
import { Observable } from 'rxjs/Rx';

import { CONFIG } from './../../config/constants';
import { TestModel } from './test.model';

@Injectable()
export class TestService {

constructor(private http: Http, @Inject(CONFIG) private config) {}

getTestsModels(): Observable<TestModel[]> {

let url = this.config.apiUrl + "test";

return this.http.get(url)
.map( (response) => response.json() )
.map( (results) => {
return results.map( (current) => {
return ReflectiveInjector.resolveAndCreate([TestModel]).get(TestModel);
})
})
.catch(this.handleError);

}

private handleError(err): Observable<any> {

let errMessage = err.message ? err.message : err.status ? `${err.status} - ${err.statusText}` : 'Server Error';

return Observable.throw(new Error(errMessage));

}

}

但后来我得到了错误:

enter image description here

然后,如果我将 Http 添加到 ReflectiveInjector,我只会得到另一个连接后端错误,我假设它会继续进入依赖链,直到我们找到底部。

抱歉发了这么长的帖子,如有任何帮助,我们将不胜感激!

最佳答案

您可以提供工厂功能。这不同于简单的 useFactory: ... 供应商

{ 
provide: 'TestModelFactory',
useFactory: () => {
return (http, config) => {
return new TestModel(http, config);
};
},
deps: [Http, CONFIG];
}

然后像这样使用它

@Injectable()
export class TestService {

constructor(@Inject('TestModelFactory' testModelFactory) {}

getTestsModels(): Observable<TestModel[]> {
let url = this.config.apiUrl + "test";
return this.http.get(url)
.map( (response) => response.json() )
.map( (results) => {
return results.map( (current) => {
let tm = testModelFactory();
tm.xxx // assign data
})
})
.catch(this.handleError);
}
}

您还可以支持每个实例的参数,例如

{ 
provide: 'TestModelFactory',
useFactory: (json) => {
return (http, config) => {
return new TestModel(http, config, json);
};
},
deps: [Http, CONFIG];
}

然后像这样使用它

@Injectable()
export class TestService {

constructor(@Inject('TestModelFactory' testModelFactory) {}

getTestsModels(): Observable<TestModel[]> {
let url = this.config.apiUrl + "test";
return this.http.get(url)
.map( (response) => response.json() )
.map( (results) => {
return results.map( (current) => {
let tm = testModelFactory(result);
})
})
.catch(this.handleError);
}
}

但您并不需要使用 DI。您已经将 HttpCONFIG 注入(inject)到您的 TestService 中。你可以

@Injectable()
export class TestService {

constructor(private http: Http, @Inject(CONFIG) private config) {}

getTestsModels(): Observable<TestModel[]> {

let url = this.config.apiUrl + "test";

return this.http.get(url)
.map( (response) => response.json() )
.map( (results) => {
return results.map( (current) => {
return new TestModel(http, config);
})
})
.catch(this.handleError);

}

private handleError(err): Observable<any> {

let errMessage = err.message ? err.message : err.status ? `${err.status} - ${err.statusText}` : 'Server Error';

return Observable.throw(new Error(errMessage));

}
}

在每种情况下,您都需要提供一些方法来从 result 初始化 TestModel,例如通过将 JSON 传递给构造函数并初始化 TestModel< 的成员 来自传递的 JSON。

另见 Angular2: How to use multiple instances of same Service?

关于angular - 创建具有依赖关系的类的新实例,不了解工厂提供者,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38472103/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com