将异步数据作为参数传递给组件

时间:2017-07-17 20:00:36

标签: angular typescript asynchronous

我正在尝试创建一个自定义选择组件,其异步加载数据并作为参数传递。这是我的组成部分:

@Component({
    selector: 'custom-select-combo',
    template:
    `<select #CustomSelectCombobox
        class="form-control"
        [(ngModel)]="selectedOption"
        (ngModelChange)="selectedOptionChange.emit($event)"
        [attr.data-live-search]="true">        
            <option *ngFor="let item of items | async" [value]="item">{{item}}</option>
    </select>`
})
export class CustomSelectComboComponent extends AppComponentBase implements OnInit, AfterViewInit {

    @ViewChild('CustomSelectCombobox') customSelectComboboxElement: ElementRef;

    @Input() selectedOption: string = undefined;
    @Input() items: string[];
    @Output() selectedOptionChange: EventEmitter<string> = new EventEmitter<string>();

    constructor(
        injector: Injector) {
        super(injector);
    }

    ngOnInit(): void {
        const self = this;
        setTimeout(() => {
            $(self.customSelectComboboxElement.nativeElement).selectpicker('refresh');
        }, 0);
    }

    ngAfterViewInit(): void {
        $(this.customSelectComboboxElement.nativeElement).selectpicker({
            iconBase: 'famfamfam-flag',
            tickIcon: 'fa fa-check'
        });
    }
}

这是html:

<div class="col-xs-6">
    <custom-select-combo [items]="tipoItems"></custom-select-combo>
</div>

这就是我加载数据的地方:

tipoItems = [];

constructor(
    injector: Injector,
    private _tipoDadoService: TipoDadoServiceProxy,
) {
    super(injector);
    this._tipoDadoService.getAllTipos()
        .subscribe((result) => {
            this.tipoItems = result;
        });
}

当我尝试运行此实际代码时,我在控制台中收到错误:

  

“ERROR错误:InvalidPipeArgument:''用于管道'AsyncPipe'”

还有很多

  

“ERROR TypeError:无法读取属性'dispose'为null”。

我尝试阅读一些教程,但我仍然无法使其工作。

@edit: 服务类,按要求:

@Injectable()
export class TipoDadoServiceProxy {
    private http: Http;
    private baseUrl: string;
    protected jsonParseReviver: (key: string, value: any) => any = undefined;

    constructor(@Inject(Http) http: Http, @Optional() @Inject(API_BASE_URL) baseUrl?: string) {
        this.http = http;
        this.baseUrl = baseUrl ? baseUrl : "";
    }
    /* Whole bunch of other functions here... */

    /**
     * @return Success
     */
    getAllTipos(): Observable<string[]> {
        let url_ = this.baseUrl + "/api/services/app/TipoDado/GetAllTipos";
        url_ = url_.replace(/[?&]$/, "");

        const content_ = "";

        let options_ = {
            body: content_,
            method: "get",
            headers: new Headers({
                "Content-Type": "application/json; charset=UTF-8", 
                "Accept": "application/json; charset=UTF-8"
            })
        };

        return this.http.request(url_, options_).flatMap((response_) => {
            return this.processGetAllTipos(response_);
        }).catch((response_: any) => {
            if (response_ instanceof Response) {
                try {
                    return this.processGetAllTipos(response_);
                } catch (e) {
                    return <Observable<string[]>><any>Observable.throw(e);
                }
            } else
                return <Observable<string[]>><any>Observable.throw(response_);
        });
    }

    protected processGetAllTipos(response: Response): Observable<string[]> {
        const status = response.status; 

        if (status === 200) {
            const responseText = response.text();
            let result200: string[] = null;
            let resultData200 = responseText === "" ? null : JSON.parse(responseText, this.jsonParseReviver);
            if (resultData200 && resultData200.constructor === Array) {
                result200 = [];
                for (let item of resultData200)
                    result200.push(item);
            }
            return Observable.of(result200);
        } else if (status !== 200 && status !== 204) {
            const responseText = response.text();
            return throwException("An unexpected server error occurred.", status, responseText);
        }
        return Observable.of<string[]>(<any>null);
    }


}

2 个答案:

答案 0 :(得分:0)

试试吧

for HTML

<div class="col-xs-6" *ngIf="(tipoDadoService.getAllTipos | async) && tipoDadoService.getAllTipos.getValue().length">
    <custom-select-combo [items]="_tipoDadoService.getAllTipos.getValue()"></custom-select-combo>
</div>

for component

constructor( 
    public tipoDadoService: TipoDadoServiceProxy,
) { 
}

答案 1 :(得分:0)

最好使用ControlValueAccessor。这需要实现少量方法,然后您就可以使用ngModel或将此自定义组件用作表单控件。 此处的示例:https://jenniferwadella.com/blog/Angular-2-forms-CVA-intro