0

我是 Angular 的新手。我有一个 Node 和 Express 后端从 MS SQL 数据库中提取数据。如果我转到端点 URL,它会将我的数据显示为 JSON。我在本地主机上运行,​​所以我为 CORS 设置了一个代理。我有一个定义数据的类,一个从端点提取数据的服务,以及一个尝试将数组设置为等于从服务中提取的数据的组件。HTML 有一个 *ngFor,它应该循环遍历这些值并将它们显示在网格中。

如果我通过我的服务调用我的组件中的数据,那么 this.userService.getUsers() 并执行 console.log,我可以在浏览器控制台中看到记录集。我尝试将数组设置为等于 userService.getUsers() 然后调用该数组,我得到“未定义”。由于我是新手,所以我尝试按照英雄教程进行操作,但没有成功。我花了一天时间搜索谷歌并尝试了我遇到的不同解决方案,但它们都未定义。我将在此处附上代码。如果有人可以指导我一点,将不胜感激。

定义用户的用户类:

export class User{
    id: number;
    ccn: string;
    firstName: string;
    lastName: string;
    email: string;
}

用户服务做 Http 请求:

import { Injectable } from '@angular/core';
import { User } from './user';
import { USERS } from './mock-users';
import { MessageService } from './message.service';
import { Observable, of } from 'rxjs';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { catchError, map, tap } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class UserService {

  private userURL = 'api/users'
  //private userURL = 'localhost:5000'

  httpOptions = {
    headers: new HttpHeaders({ 'Content-Type': 'application/json' })
  };

  constructor(
    private http: HttpClient,
    private messageService: MessageService) { }

  //getUsers(): Observable<User[]> {
  //  this.messageService.add('UserService: fetched users');
  //  return of(USERS);
  //}

  /** GET users from the server */
  getUsers(): Observable<User[]> {
    //console.log('getting users');
    return this.http.get<User[]>("http://localhost:5000/api/user")
      .pipe(
        tap(_ => this.log('Fetched users')),
        catchError(this.handleError<User[]>('getUsers', []))
      );
      //return this.http.get<User[]>("http://localhost:5000/api/user");
      //console.log('got users');
  }

  /* GET heroes whose name contains search term */
  searchUsers(term: string): Observable<User[]> {
    if (!term.trim()) {
      // if not search term, return empty hero array.
      return of([]);
    }
    return this.http.get<User[]>(`${this.userURL}/?ccn=${term}`).pipe(
      tap(_ => this.log(`found users matching "${term}"`)),
      catchError(this.handleError<User[]>('searchUsers', []))
    );
  }

  addUser (user: User): Observable<User> {
    return this.http.post<User>(this.userURL, user, this.httpOptions).pipe(
      tap((newUser: User) => this.log(`added user w/ id=${newUser.id}`)),
      catchError(this.handleError<User>('addUser'))
    );
  }

  private handleError<T> (operation = 'operation', result?: T) {
    return (error: any): Observable<T> => {
      console.error(error);

      this.log(`${operation} failed: ${error.message}`);

      return of(result as T);
    };
  }

  private log(message: string) {
    this.messageService.add(`User service: ${message}`);
  }
}

显示用户组件 TS 文件:

import { Component, OnInit } from '@angular/core';
//import { USERS } from '../mock-users';
import { UserService } from '../user.service';
import { User } from '../user';
import { Observable, of } from 'rxjs';
import { catchError, map, tap } from 'rxjs/operators';
import { element } from 'protractor';

@Component({
  selector: 'app-display-users',
  templateUrl: './display-users.component.html',
  styleUrls: ['./display-users.component.css']
})
export class DisplayUsersComponent implements OnInit {
  users: User[] = [];

  constructor(private userService: UserService) { }

  //users$ = this.getUsers();

  ngOnInit() {
    this.getUsers();
    console.log(this.userService.getUsers());
    this.userService.getUsers().forEach(element => {
      console.log(element);
    });
  }

  getUsers(): void {
    /*this.userService.getUsers()
    .subscribe(users => this.users = users);*/
    const userObservable = this.userService.getUsers();
    userObservable.subscribe((userData: User[]) => {
      this.users = userData;
    });
  }

}

显示用户组件 HTML:

<div class="clr-row">
    <div class="clr-col-lg-11 clr-col-md-11 clr-col-11 main-div">
        <div class="card card-style" style="box-shadow: 0 0 0 0;">
            <div class="card-header">
                <h1><img src="../assets/images/BSOLOGO_gray.png" class="title-img"><span class="title">&nbsp;&nbsp;Users</span></h1>
            </div>
            <div class="card-block">
                <div class="card-title">
                    <clr-datagrid>
                        <clr-dg-column>CCN</clr-dg-column>
                        <clr-dg-column>Last Name</clr-dg-column>
                        <clr-dg-column>First Name</clr-dg-column>
                        <clr-dg-column>Email</clr-dg-column>

                        <clr-dg-row *ngFor="let user of users">
                            <clr-dg-cell>{{user.ccn}}</clr-dg-cell>
                            <clr-dg-cell>{{user.lastName}}</clr-dg-cell>
                            <clr-dg-cell>{{user.firstName}}</clr-dg-cell>
                            <clr-dg-cell>{{user.email}}</clr-dg-cell>
                        </clr-dg-row>

                        <clr-dg-footer>{{users.length}} users</clr-dg-footer>
                    </clr-datagrid>
                </div>
            </div>
        </div>
    </div>
</div>

任何帮助将不胜感激!

更新 在此处输入图像描述

4

3 回答 3

0

Ypu 可以用这些替换两个类上的 getUsers。HTML 对我来说看起来不错。我也将用户转换为公众。

//userService
getUsers(callback: Function) {
    return this.http.get<User[]>("http://localhost:5000/api/user")
      .subscribe(
        response => callback(response)
      );
  }

//Component
public users: User[] = [];
getUsers(): void {
    this.userService.getUsers((result) => {this.users = result;})
  }
于 2020-01-07T01:46:50.747 回答
0

如果您不需要它是可观察的,您可以使用 toPromise() 并使用 async/await 使它更容易

服务

  async getUsers(): Promise<User[]> {
    return await this.http.get<User[]>('http://localhost:5000/api/user').toPromise();
  }

组件.ts

  users: User[] = [];

  async ngOnInit() {
    this.users = await this.userService.getUsers();
  }

组件.html

                 <clr-datagrid *ngIf="users">
                    <clr-dg-column>CCN</clr-dg-column>
                    <clr-dg-column>Last Name</clr-dg-column>
                    <clr-dg-column>First Name</clr-dg-column>
                    <clr-dg-column>Email</clr-dg-column>

                    <clr-dg-row *ngFor="let user of users">
                        <clr-dg-cell>{{user.ccn}}</clr-dg-cell>
                        <clr-dg-cell>{{user.lastName}}</clr-dg-cell>
                        <clr-dg-cell>{{user.firstName}}</clr-dg-cell>
                        <clr-dg-cell>{{user.email}}</clr-dg-cell>
                    </clr-dg-row>

                    <clr-dg-footer>{{users.length}} users</clr-dg-footer>
                </clr-datagrid>
于 2020-01-08T01:23:47.130 回答
0

我的问题已经解决。在我的 SQL 语句中,我调用了 SELECT * FROM table FOR JSON PATH,它正在创建一个从服务器中提取的奇怪对象。删除 FOR JSON PATH 提供的 JSON 数据。然后我的问题的第二部分是将我的数据库字段映射到我的用户类。

这样做是这样的:

    request.query('SELECT * FROM Table ORDER BY myField', function (err, recordset) {
        if (err) console.log(err);    
        const records = recordset.recordset;
        const result = records.map(r => { return { id: r.tableID, field1: r.dbField1, field2: r.dbField2, field3: r.dbField3, field4: r.dbField4}});
        res.send(result);
    });

我希望这可以帮助别人!感谢所有发帖帮助我的人。

于 2020-01-09T02:20:14.123 回答