【问题标题】:How to handle async data in ngOnInit (routing with parameter) Angular 4如何在ngOnInit(带参数的路由)Angular 4中处理异步数据
【发布时间】:2018-02-19 13:15:56
【问题描述】:

我正在尝试从我的 Web api 控制器加载数据。 目前我正在使用我从组件的 ngOnInit 函数调用的 API 服务。 但是,视图中没有返回任何内容,因为它是异步数据

Web api 控制器

[HttpGet("[action]")]
    public async Task<UserModel> GetUserById(int id)
    {
        Response.StatusCode = 200;
        try
        {
            _context = new AuthentificationDbContext();
            UserModel user = await _context.User.SingleOrDefaultAsync(m => m.id == id);
            if (user == null)
            {
                return null;
            }
            else
              return (user);
        }
        catch (SqlException ex)
        {
            throw ex;

        }
    }

userService.ts

getUserId(id: number) : Observable<User>{
    return this.http.get(this.url + 'userApi/GetUserById/?id=' + id)
        .map(res => <User>res.json())
        .catch(this.handleError);
}

app.routing.ts

{ path: 'user/:id', component: UserComponent}
export const routing = RouterModule.forRoot(appRoutes,{ 
                                            enableTracing:true});
export const routedComponents = [UserComponent];

user.component.ts

export class UserComponent implements OnInit {
private user: User;
constructor(private userService: UserService, private route: ActivatedRoute, private router: Router) { }

    ngOnInit() {  
           this.route.paramMap
                    .switchMap((params: ParamMap) =>
                        this.userService.getUserId(+params.get('id')))
                    .subscribe((user: User) => {
                        this.user = user;
                    });

    }

}

user.cshtml

<div *ngIf="user">{{ user.name}}</div>

但是,当我尝试使用该示例时,这是可行的,因为它不是异步的

import { Injectable, Inject } from '@angular/core';
import { Http, Response, RequestOptions, Headers } from '@angular/http';
import { Observable } from 'rxjs/Observable';
export class User {
constructor(public id: number, public name: string) { }
}
let Users = [
new User(11, 'Mr. Nice'),
new User(12, 'Narco')
];
let usersPromise = Promise.resolve(Users);
@Injectable()
export class UserService {
constructor( @Inject(Http) public http: Http) { }

    getUserId(id: number | string) {
        return usersPromise
            .then(users => users.find(user => user.id === +id));
    }

}

我的问题:如何在 ngOnInit 中加载异步数据? 我也用过promise,但是没用

【问题讨论】:

  • .subscribe((user: User) => { this.user = user; 你在这里试过 console.log(this.user) 来检查你收到了什么数据吗?
  • 请在视图中添加显示您如何使用user 的代码。即使您的代码是异步的,它仍然会设置this.user(如果this.userService.getUserId(+params.get('id')) 是有效代码并最终收到响应。如果您依赖于立即可用的结果,您的代码可能会中断,但是如果没有看到代码就很难判断.
  • 是的,我正在使用 console.log(this.user) 但问题是关于 web api 控制器中的异步数据。我尝试了另一个示例,即工作 export class User { constructor(public id: number, public name: string) { } let Users = [ new User(11, 'Mr. Nice'), new User(12, 'Narco' )];让 usersPromise = Promise.resolve(Users); getUserId(id: number | string) { return usersPromise.then(users => users.find(user => user.id=== +id)); } }
  • 视图中的代码

    {{ user.name}}

  • cmets 中的代码很难阅读,请编辑您的问题并在此处添加代码。

标签: c# angular sql-server-2014-express asp.net-core-1.1


【解决方案1】:

如果你使用

{{user.view}}

在组件模板中,你会得到一个错误,因为user 不是立即可用的。

{{user?.view}}

(safe-nativation operator) 通过在user 为空时不抛出异常来避免此错误。

【讨论】:

  • 感谢 Günter,我知道问题在于用户无法立即使用。我的问题是如何在 ngOnInit 中加载异步数据?
  • 您的代码已经在异步加载数据。你有没有试过我的建议?您是否检查过是否出现错误?
  • 我尝试了你的建议,但不起作用我用调试器执行我的代码并停止,但调试器不执行 web api 控制器中的函数,只需执行 userService.ts
  • “函数”到底是什么?
  • 好的,谢谢 Günter,我认为问题与带参数的路由有关,因为我尝试了很多不带参数的示例,没有问题。我是 Angular 4 的初学者,我的第一个示例来自带参数的路由,只是时间,我会解决它。
【解决方案2】:

我可以解决我的问题(它与路由有关): 我的代码只需要插入这个:

<script>document.write('<base href="' + document.location + '" />');</script>

在“头”部分的顶部。


并且要从 app.component.ts 插入构造函数,这个方法:

click() {
    this.router.navigate(['', { foo: 'bar' }]);
}

【讨论】:

    猜你喜欢
    • 2019-07-22
    • 2018-03-08
    • 2017-09-06
    • 1970-01-01
    • 1970-01-01
    • 2016-11-06
    • 1970-01-01
    • 1970-01-01
    • 2019-08-31
    相关资源
    最近更新 更多