асинхронная труба с наблюдаемым в угловом 4

Я новичок в angular и начал склоняться к angular 4. Данные не связываются с директивой ngfor на компоненте, использующем асинхронный конвейер. Пожалуйста помоги

Пользовательский сервис использует HTTP-запрос для получения данных из API:

user.service.ts

import { Injectable } from '@angular/core';
import { Http, Response, Headers, RequestOptions } from '@angular/http';
import { Observable } from 'rxjs/Observable';
import 'rxjs/add/operator/map';
import 'rxjs/add/operator/do';
import 'rxjs/add/operator/catch';
import { User } from "../Models/user";

@Injectable()
export class UserService {
    constructor(private http: Http) { }

    get(url: string): Observable<User[]> {
        return this.http.get(url)
            .map(response => response.json() as User[])
            // .do(data => console.log("All: " + JSON.stringify(data)))
            .catch(this.handleError);
    }
    private handleError(error: Response) {
        console.error(error);
        return Observable.throw(error.json().error || 'Server error');
    }
}

Здесь я использую наблюдаемый интерфейс User [] для списка пользователей:

user.component.ts

import { Component, OnInit, ViewChild } from '@angular/core';
import { UserService } from '../Services/user.service';
import { FormBuilder, FormGroup, Validators } from '@angular/forms';
import { ModalComponent } from 'ng2-bs3-modal/ng2-bs3-modal';
import { User } from '../Models/user';
import { DBOperation } from '../Shared/enum';
import { Observable } from 'rxjs/Observable';
import { Global } from '../Shared/global';

@Component({
    templateUrl: 'app/Components/user.component.html'
})

export class UserComponent implements OnInit {
    @ViewChild('modal') modal: ModalComponent;
    users$: Observable<User[]>;
    user: User;
    msg: string;
    indLoading: boolean = false;
    userForm: FormGroup;
    dbops: DBOperation;
    modalTitle: string;
    modalBtnTitle: string

    constructor(private fb: FormBuilder, private userService: UserService) 
   { }

   ngOnInit(): void {
    this.userForm = this.fb.group({
        Id: [''],
        UserName: ['', Validators.required],
        Password: ['', Validators.required],
        FirstName: ['', Validators.required],
        LastName: ['', Validators.required],
        Gender: ['', Validators.required]
    });
    this.LoadUsers();
    }
    LoadUsers(): void {
        this.indLoading = true;
        this.users$ = this.userService.get('http://localhost:29712/api/userapi/');
        this.indLoading = false;
    }   
}

Шаблон для асинхронного канала для подписки наблюдаемой пользовательской переменной:

user.component.html

<div class='panel panel-primary'>
    <div class='panel-heading'>
        User Management
     </div>
     <div class='panel-body'>
         <div class='table-responsive'>
        <div class="alert alert-info" role="alert" *ngIf="indLoading"><img src="../../images/loading.gif" width="32" height="32" /> Loading...</div>
        <div *ngIf='users && users.length==0' class="alert alert-info" role="alert">No record found!</div>
        <table class='table table-striped' *ngIf='users && users.length'>
            <thead>
                <tr>
                    <th>First Name</th>
                    <th>Last Name</th>
                    <th>Gender</th>
                </tr>
            </thead>
            <tbody>
                <tr *ngFor="let user of users$ | async">
                    <td>{{user.FirstName}}</td>
                    <td>{{user.LastName}}</td>
                    <td>{{user.Gender}}</td>
                </tr>
            </tbody>
        </table>
        <div>
        </div>
    </div>
    <div *ngIf="msg" role="alert" class="alert alert-info alert-dismissible">
        <button type="button" class="close" data-dismiss="alert" aria-label="Close"><span aria-hidden="true">&times;</span></button>
        <span class="glyphicon glyphicon-exclamation-sign" aria-hidden="true"></span>
        <span class="sr-only">Error:</span>
        {{msg}}
    </div>
</div>


person Sajan Chhipa    schedule 30.07.2017    source источник
comment
Поскольку вы подписываетесь, вам не нужен асинхронный канал.   -  person DeborahK    schedule 30.07.2017
comment
Ваш /api/userapi/ запрос будет выполнен дважды   -  person yurzui    schedule 30.07.2017
comment
Я бы проверил, разрешается ли response => response.json() as IUser[] равным нулю. Вы уверены, что служба отвечает той же структурой данных, что и ваш IUser?   -  person dee zg    schedule 30.07.2017
comment
@deezg Его ответ правильный. Посмотрите на шаблон ngIf="users && users.length", где users обозначается   -  person yurzui    schedule 30.07.2017
comment
Да, я также получаю массив пользователей json в функции LoadUsers   -  person Sajan Chhipa    schedule 30.07.2017
comment
@yurzui ну, он на самом деле не сказал, что означает «данные не привязываются»? Означает ли это, что таблица вообще не отображается (ngIf вы упомянули, что не разрешает true) или таблица отображается, но не отображаются строки в таблице?   -  person dee zg    schedule 30.07.2017
comment
я имею в виду, что такого рода вещи должны быть построены с использованием интеллектуальных / немых компонентов, иметь @Input() в немом компоненте, установленном на Observable и проверять вещи в OnChanges. Но теперь интересно посмотреть, почему это не работает при такой настройке.   -  person dee zg    schedule 30.07.2017
comment
@deezgd да, таблица вообще не отображается   -  person yurzui    schedule 30.07.2017
comment
@yurzui ах ну тогда, конечно, ты прав. я сосредоточился на ngFor, как он сказал в вопросе. но конечно, ngIf с users наблюдаемым - это проблема.   -  person dee zg    schedule 30.07.2017
comment
@deezg, вы правы, пользователи наблюдаются, я удалил условие, и теперь список пользователей отображается   -  person Sajan Chhipa    schedule 30.07.2017
comment
Кредиты @Sajan отправляются на @yurzui. Он указал на ngIf;)   -  person dee zg    schedule 30.07.2017


Ответы (2)


Поскольку вы используете async. Попробуйте удалить подписку. в исходном коде. Вот видео о чем-то похожем . Действительно полезно использовать $ для наблюдаемых свойств ...

person JGFMK    schedule 30.07.2017
comment
Затем он должен изменить эту часть let user of users | async также в шаблоне. - person yurzui; 30.07.2017
comment
Выдает ошибку, что тип «IUser» не может быть назначен типу «Observable‹ IUser [] ›», потому что this.users является типом «Observable‹ IUser [] ›» - person Sajan Chhipa; 30.07.2017
comment
К вашему сведению: github.com/Microsoft/TypeScript/wiki/Coding-guidelines - Не помещайте I для интерфейсов или _ для частных экземпляров ... Я также обычно ставлю $ в конце переменной, чтобы указать, что это наблюдаемое. Так что я бы позволил пользователю пользователей $ | async и изменить свойство в классе - person JGFMK; 30.07.2017
comment
Ошибок не возникает. Это не привязывает список пользователей к шаблону - person Sajan Chhipa; 30.07.2017

Ваш * ngIf создает проблему, вы не можете напрямую проверить свою наблюдаемую длину без async pipe. Попробуй это,

*ngIf="(users$ | async)?.length==0"
person Usman Hussain    schedule 30.07.2017
comment
Но длина 0 означает, что данных нет, и он вызовет еще один HTTP-вызов. - person yurzui; 30.07.2017
comment
Я бы разрешил асинхронный канал один раз, используя users$ | async as users - person yurzui; 30.07.2017
comment
Почему он вызвал еще один api. Функция this.loads срабатывает при запуске ngOnInit и будет вызывать api. - person Usman Hussain; 30.07.2017
comment
У нас будет две подписки в ngIf и ngFor. - person yurzui; 30.07.2017
comment
@yurzui просто для добавления ссылки в документы: angular.io/api/common/NgIf. Часть с 'сохранением условного результата в переменной' - person dee zg; 30.07.2017