Javascript Angular2:类型“订阅”不可分配给类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/38285046/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Angular2 : Type 'Subscription' is not assignable to type
提问by Kamran Pervaiz
I have created a very small application to fetch countries from a json file and bind it to dropdown.
我创建了一个非常小的应用程序来从 json 文件中获取国家并将其绑定到下拉列表。
countries.json
国家.json
export class Country {
id: number;
name: string;
}
factory.service.ts
工厂服务.ts
import { Injectable } from '@angular/core';
import { Http, Response} from '@angular/http';
import { Observable } from 'rxjs/Observable';
import { Country } from './shared/country';
@Injectable()
export class FactoryService {
private countryUrl = "app/data/countries.json";
constructor(private http: Http) {
}
getCountry(): Observable<any> {
return this.http.get(this.countryUrl)
.map(this.extractData)
.do(data => console.log("get Countries from json: " + JSON.stringify(data)))
.catch(this.handleError);
}
private extractData(response: Response) {
let body = response.json();
return body || {};
}
private handleError(error: Response) {
console.log(error);
return Observable.throw(error.json().error || "500 internal server error");
}
}
factory-form.component.ts
工厂form.component.ts
import { Component, OnInit } from '@angular/core';
import { NgForm } from '@angular/forms';
import { Factory } from './factory';
import { Country } from './shared/country';
import { FactoryService } from './factory.service';
@Component({
moduleId: module.id,
selector: 'factory-form',
templateUrl: './factory-form.component.html',
styleUrls: ['./factory-form.component.css'],
providers: [FactoryService]
})
export class FactoryFormComponent implements OnInit{
private model: Factory;
countries: Country[];
factoryStatuses;
productTypes;
risks;
private errorMessage: string;
private submitted = false;
constructor(private factoryService: FactoryService) {
}
ngOnInit(): void {
this.countries = this.factoryService.getCountry()
.subscribe(countries => this.countries = countries,
error => this.errorMessage = error);
}
onSubmit(): void {
this.submitted = true;
}}
factory-form.component.html snippet
factory-form.component.html 片段
<div class="col-lg-3">
<select class="form-control" name="Country">
<option *ngFor="let country of countries" [value]="country.id">{{country.name}}</option>
</select>
</div>
I am getting runtime error as below:
我收到如下运行时错误:
Error: Typescript found the following errors:
C:/Projects/ethical_resourcing/src/Ethos.Client/tmp/broccoli_type_script_compiler-input_base_path-kviWq7F3.tmp/0/src/app/factory/factory-form.component.ts (30, 9): Type 'Subscription' is not assignable to type 'Country[]'.
Property 'length' is missing in type 'Subscription'.
C:/Projects/ethical_resourcing/src/Ethos.Client/tmp/broccoli_type_script_compiler-input_base_path-kviWq7F3.tmp/0/src/app/factory/shared/country.ts (2, 15): ';' expected. at BroccoliTypeScriptCompiler._doIncrementalBuild (C:\Projects\ethical_resourcing\src\Ethos.Client\node_modules\angular-cli\lib\broccoli\broccoli-typescript.js:120:19) at BroccoliTypeScriptCompiler.build (C:\Projects\ethical_resourcing\src\Ethos.Client\node_modules\angular-cli\lib\broccoli\broccoli-typescript.js:43:10) at C:\Projects\ethical_resourcing\src\Ethos.Client\node_modules\angular-cli\node_modules\broccoli-caching-writer\index.js:152:21 at lib$rsvp$$internal$$tryCatch (C:\Projects\ethical_resourcing\src\Ethos.Client\node_modules\angular-cli\node_modules\rsvp\dist\rsvp.js:1036:16) at lib$rsvp$$internal$$invokeCallback (C:\Projects\ethical_resourcing\src\Ethos.Client\node_modules\angular-cli\node_modules\rsvp\dist\rsvp.js:1048:17) at lib$rsvp$$internal$$publish (C:\Projects\ethical_resourcing\src\Ethos.Client\node_modules\angular-cli\node_modules\rsvp\dist\rsvp.js:1019:11) at lib$rsvp$asap$$flush (C:\Projects\ethical_resourcing\src\Ethos.Client\node_modules\angular-cli\node_modules\rsvp\dist\rsvp.js:1198:9) at nextTickCallbackWith0Args (node.js:420:9) at process._tickCallback (node.js:349:13)
错误:Typescript 发现以下错误:
C:/Projects/ethical_resourcing/src/Ethos.Client/tmp/broccoli_type_script_compiler-input_base_path-kviWq7F3.tmp/0/src/app/factory/factory-form.component.ts (30, 9 ):类型“订阅”不能分配给类型“国家[]”。
“订阅”类型中缺少属性“长度”。
C:/Projects/ethical_resourcing/src/Ethos.Client/tmp/broccoli_type_script_compiler-input_base_path-kviWq7F3.tmp/0/src/app/factory/shared/country.ts (2, 15): ';' 预期的。在 BroccoliTypeScriptCompiler._doIncrementalBuild (C:\Projects\ethical_resourcing\src\Ethos.Client\node_modules\angular-cli\lib\broccoli\broccoli-typescript.js:120:19) 在 BroccoliTypeScriptCompiler.build (C:\Projects\ethical_resourcing\ src\Ethos.Client\node_modules\angular-cli\lib\broccoli\broccoli-typescript.js:43:10) 在 C:\Projects\ethical_resourcing\src\Ethos.Client\node_modules\angular-cli\node_modules\broccoli- caching-writer\index.js:152:21 at lib$rsvp$$internal$$tryCatch (C:\Projects\ethical_resourcing\src\Ethos.Client\node_modules\angular-cli\node_modules\rsvp\dist\rsvp.js :1036:16) 在 lib$rsvp$$internal$$invokeCallback (C:
Now If I change the Type of Observableand countriesto any then i get below error
现在,如果我将Observable的类型和国家/地区更改为任何,则会出现以下错误
ORIGINAL EXCEPTION: Cannot find a differ supporting object '[object Object]' of type 'object'. NgFor only supports binding to Iterables such as Arrays.
原始例外:找不到类型为“object”的不同支持对象“[object Object]”。NgFor 仅支持绑定到可迭代对象,例如数组。
采纳答案by dfsq
Yes, the type must be an Observable
and the you need to use async pipe to make ngFor
happy:
是的,类型必须是 anObservable
并且您需要使用异步管道才能ngFor
开心:
*ngFor="let country of countries | async"
Or another option is to keep Country[]
type but then subscribe and assign countries
to array:
或者另一种选择是保留Country[]
类型,然后订阅并分配countries
给数组:
this.factoryService.getCountry() // note, removed this.countries =
.subscribe(
countries => this.countries = countries,
error => this.errorMessage = error
);