Angular让我发疯。
我有两个按钮。如果我点击第一个,我想提出这个请求:
https://localhost:44373/api/events
如果我点击第二个,我想提出这个请求:
https://localhost:44373/api/events/1
方法“getNextPost()”将被调用,它似乎工作,但在服务器端,将不会调用寻址的方法。
这是我的客户端实现:
export class AppComponent implements OnInit {
title = 'EventsPresenter';
_hubconnection : signalR.HubConnection;
_notification : string = '';
displayedColumns: string[] = ['eventDateTime', 'nbr', 'element', 'parent', 'stateTypeTitle', 'enumValueTitle', 'customerObject'];
ROOT_URL = 'https://localhost:44373/';
ROOT_API_URL = this.ROOT_URL + 'api/';
dataSource: Observable<EventData[]>;
dataSource2: Observable<EventData>;
constructor(private http: HttpClient) {}
getPosts(){
this.dataSource = this.http.get<EventData[]>(this.ROOT_API_URL + 'events')
}
getNextPost(){
this.dataSource2 = this.http.get<EventData>(this.ROOT_API_URL + 'events/1')
}
ngOnInit() {
this._hubconnection = new signalR.HubConnectionBuilder()
.configureLogging(signalR.LogLevel.Trace)
.withUrl('https://localhost:44373/notify')
.build();
this._hubconnection
.start()
.then(() => console.log('Connection Started'))
.catch(err => console.log('Error while establishing connection'));
this._hubconnection.on('BroadcastMessage', (data: EventData) => {
console.log(data);
this.dataSource.subscribe(v => v.push(data));
});
}
}
这是我的服务器实现:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using convisAPI.DataProvider;
using convisAPI.Interfaces;
using EntityLibrary;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.SignalR;
namespace convisAPI.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class EventsController : ControllerBase
{
//EventDataProvider eventDataProvider;
IEventDataRepository _eventDataRepository;
IHubContext<NotifyHub> _hubContext;
public EventsController(IEventDataRepository eventDataRepository, IHubContext<NotifyHub> hubContext)
{
_eventDataRepository = eventDataRepository;
_hubContext = hubContext;
}
// GET api/events
[HttpGet]
public async Task<ActionResult<IEnumerable<EventSummary>>> Get()
{
return await _eventDataRepository.GetEvents();
}
// GET api/values/5
[HttpGet("{id}")]
public async Task<ActionResult<EventSummary>> Get(int id)
{
Random r = new Random();
var ra = r.Next(212, 220);
await _hubContext.Clients.All.SendAsync("BroadcastMessage", new EventSummary()
{
Element = "Mein Element " + ra,
Details = "Das ist mein Eventgrund",
EventID = Guid.NewGuid(),
ElementID = Guid.NewGuid(),
EventDateTime = DateTime.Now,
Nbr = ra,
StateNbr = ra,
EnumValueTitle = "Störung",
StateEnumValue = 110 + ra
});
return new EventSummary();
}
// POST api/values
[HttpPost]
public void Post([FromBody] string value)
{
}
// PUT api/values/5
[HttpPut("{id}")]
public void Put(int id, [FromBody] string value)
{
}
// DELETE api/values/5
[HttpDelete("{id}")]
public void Delete(int id)
{
}
}
}
我知道代码“Get(int id)”可能看起来很奇怪,但我基本上想要触发SignalR通知。
有任何想法吗?
最好的祝福
在Angular中,每个HTTP请求只会在有人听到它们时“触发”。
所以,如果没有人订阅,那么就不会有任何http请求。
getPosts(){
this.http.get<EventData[]>(this.ROOT_API_URL + 'events')
.subscribe(result => this.dataSource = result)
}
getNextPost(){
this.http.get<`EventData>(this.ROOT_API_URL + 'events/1')
.subscribe(result => this.dataSource2 = result)
}
我会写它有点不同,但那是个人风格而不是
getPosts(){
this.dataSource = this.http.get<EventData[]>(this.ROOT_API_URL + 'events')
}
我会写的
getPosts():Observable<EventData[]>{
return this.http.get<EventData[]>(this.ROOT_API_URL + 'events')
}
然后我会订阅我需要数据的点。
...
this.getPosts().subscribe(result => this.isWhereINeedit = result)
温暖的问候
这里有2个问题。
1st:HttpClient.get()方法返回一个Observable。除非订阅,否则Observable不会被触发/触发。对于Ex:
/* This wont work because it is not subscribed. */
someMethod() {
http.get(someUrl);
}
// this is work since it is subscribed.
someMethod() {
http.get(someUrl).subscribe(res => console.log(res));
}
因此,在您的情况下,没有进行对服务器的调用。检查浏览器的网络。如果进行了呼叫,那么它应该显示在那里。
第二名:CORS ISSUE。由于请求到服务器的起源和来自服务器的响应不同,因此您可能遇到了cors问题。在开发阶段,您可以使用浏览器插件来解决这个问题,但在生产过程中(当您上线时)它仍会出现。要正确解决它,需要在服务器端进行一些更改。在您的服务器上添加这些:
// Website you wish to allow to connect
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8888');
// Request methods you wish to allow
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, OPTIONS, PUT, PATCH, DELETE');
// Request headers you wish to allow
res.setHeader('Access-Control-Allow-Headers', 'X-Requested-With,content-type');
// Set to true if you need the website to include cookies in the requests sent
// to the API (e.g. in case you use sessions)
res.setHeader('Access-Control-Allow-Credentials', true);