Структура проекта
my-post.service.ts - сервис, который обменивается данными с сервером
my-post-interface.ts - структура данных
my-post.component.ts - компонент, который этот сервис использует
Сервис (Injectable )
import { Injectable, OnInit } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { MyPostInterface } from './my-post-interface';
@Injectable({
providedIn: 'root'
})
export class MyPostService {
myData = [];
myUrl = 'http://angularhttp/myAngularPostV4.php';
constructor(private myHttp: HttpClient) { }
sendRequest() {
this.myHttp.post(this.myUrl, {observe: 'body', responseType: 'json'})
.subscribe({
next: data => console.log('Request N: ' , this.myData.push(data)),
error: err => console.error('Error: ' + err),
complete: () => console.log('Complete'),});
return this.myData;
}
}
Интерфейс
export interface MyDataInterface {
id: number;
name: string;
title: string;
msg: string;
}
Компонент
import { Component, OnInit } from '@angular/core';
import { MyPostService } from '../my-post.service';
@Component({
selector: 'app-my-post',
templateUrl: './my-post.component.html',
styleUrls: ['./my-post.component.css']
})
export class MyPostComponent implements OnInit {
myDataArray = [];
constructor(private connectToServer: MyPostService) { }
ngOnInit() { }
getData() {
this.myDataArray = this.connectToServer.sendRequest();
}
}
app-module
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { HttpClientModule } from '@angular/common/http'
import { MyPostService } from './my-post.service';
import { MyPostComponent } from './my-post/my-post.component';
@NgModule({
declarations: [
AppComponent,
MyPostComponent
],
imports: [
BrowserModule,
HttpClientModule
],
providers: [MyPostService],
bootstrap: [AppComponent]
})
export class AppModule { }
Шаблон компонента
import { Component, OnInit } from '@angular/core';
import { MyPostService } from '../my-post.service';
@Component({
selector: 'app-my-post',
templateUrl: './my-post.component.html',
styleUrls: ['./my-post.component.css']
})
export class MyPostComponent implements OnInit {
myDataArray = [];
constructor(private connectToServer: MyPostService) { }
ngOnInit() { }
getData() {
this.myDataArray = this.connectToServer.sendRequest();
}
}
Стили компонента
TABLE {
border-collapse: collapse;
width: 100%;
}
TABLE TH {
color: red;
font-size: 1.2rem;
}
TABLE TH,
TABLE TD {
border: 1px solid lightgray;
padding: 5px;
}
.testbutton {
color: #14396A;
text-shadow: 1px 1px 0px #7CACDE;
box-shadow: 1px 1px 1px #BEE2F9;
padding: 10px 25px;
border-radius: 10px;
border: 2px solid #3866A3;
background: #63B8EE;
background: linear-gradient(to bottom, #63B8EE, #468CCF);
}
.testbutton:hover {
color: #F00;
background: #468CCF;
background: linear-gradient(to bottom, #468CCF, #63B8EE);
}
Результат - до запроса к серверу
После запроса
Поиск данных на сервере
Пошлём серверу имя пользователя (Anna), чтобы получить полную информации о нём
Сервис
import { Injectable, OnInit } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { MyPostInterface } from './my-post-interface';
@Injectable({
providedIn: 'root'
})
export class MyPostService {
constructor(private myHttp: HttpClient) { }
sendRequest() {
const myUrl = 'http://angularhttp/myAngularPostV4.php';
let myData = [];
this.myHttp.post(myUrl, {observe: 'body', responseType: 'json'})
.subscribe({
next: data => console.log('Server requested: ' , myData.push(data)),
error: err => console.error('Error: ' + err),
complete: () => console.log('Complete'),});
return myData;
}
getUserData() {
const myUrl = 'http://angularhttp/myAngularPostV5.php';
const myHeaders = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
let myData = [];
this.myHttp.post(myUrl, {name : 'Anna'}, {headers: myHeaders, observe: 'body', responseType: 'json'})
.subscribe({
next: data => console.log('Server requested: ' , myData.push(data)),
error: err => console.error('Error: ' + err),
complete: () => console.log('Complete'),});
return myData;
}
}
Компонент
import { Component, OnInit } from '@angular/core';
import { MyPostService } from '../my-post.service';
@Component({
selector: 'app-my-post',
templateUrl: './my-post.component.html',
styleUrls: ['./my-post.component.css']
})
export class MyPostComponent implements OnInit {
allUsers = [];
foundUser = [];
constructor(private connectToServer: MyPostService) { }
ngOnInit() { }
getAllData() {
this.allUsers = this.connectToServer.sendRequest();
}
getUserData() {
this.foundUser = this.connectToServer.getUserData();
}
}
Шаблон компонента
<h1>POST test component</h1>
<hr>
<button class='testbutton' (click)='getAllData()'>Request all data from server</button>
<table>
<tr>
<th>ID</th>
<th>Name</th>
<th>Position</th>
<th>Remarks</th>
</tr>
<tr *ngFor='let str of allUsers[0]'>
<td>{{str['id']}}</td>
<td>{{str['name']}}</td>
<td>{{str['title']}}</td>
<td>{{str['msg']}}</td>
</tr>
</table>
<hr>
<button class='testbutton' (click)='getUserData()'>Get user data</button>
<table>
<tr>
<th>ID</th>
<th>Name</th>
<th>Position</th>
<th>Remarks</th>
</tr>
<tr *ngFor='let str of foundUser[0]'>
<td>{{str['id']}}</td>
<td>{{str['name']}}</td>
<td>{{str['title']}}</td>
<td>{{str['msg']}}</td>
</tr>
</table>
<hr>
app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { HttpClientModule } from '@angular/common/http'
import { MyPostService } from './my-post.service';
import { MyPostComponent } from './my-post/my-post.component';
@NgModule({
declarations: [
AppComponent,
MyPostComponent
],
imports: [
BrowserModule,
HttpClientModule
],
providers: [MyPostService],
bootstrap: [AppComponent]
})
export class AppModule { }
Результат
Server side
Используется Apache на локальном компьютере. Адрес сервера: http://angularhttp/ Запросы обрабатывает PHP - программа myAngularPostV4.php.
Формат данных и способ их интерпретации зависит от HTTP заголовков (руфвукы), которые выставлены и в Angular
const myHeaders = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
и
{observe: 'body', responseType: 'json'}
и в PHP
header('Content-type: application/x-www-form-urlencoded; charset=UTF-8');
PHP должен интерпретировать то, что посылает Angular через метод subscribe() объекта Observable. Если при посылке меняем формат, то и в PHP его надо менять.
Программа PHP получает запрос от Angular и в ответ посылает строку с данными (в формате JSON) - myAngularPostV4.php
<?php
header('Access-Control-Allow-Origin: http://localhost:4200');
header('Content-type: application/json');
header("Access-Control-Allow-Headers: *");
header('Access-Control-Allow-Methods: POST');
$outstr = '[{
"id" : 1000,
"name" : "Anna",
"title" : "Manager",
"msg" : "Sales department"
},
{
"id" : 1001,
"name" : "Bob",
"title" : "Technician",
"msg" : "Server support team"
},
{
"id" : 1002,
"name" : "Alex",
"title" : "WEB developer",
"msg" : "Corporate web development team"
}
]';
echo($outstr);
?>
Эхо - тест (получили запрос - отдали то, что получили) - myAngularPostV3.php
<?php
header('Access-Control-Allow-Origin: http://localhost:4200');
header('Content-type: application/json');
header("Access-Control-Allow-Headers: *");
header('Access-Control-Allow-Methods: POST');
$_POST = json_decode(file_get_contents('php://input'), true);
$id = $_POST['id'];
$name = $_POST['name'];
$title = $_POST['title'];
$msg = $_POST['msg'];
$outstr = '[{ ';
$outstr .= '"id": "';
$outstr .= $id;
$outstr .= '", "name": "';
$outstr .= $name;
$outstr .= '", "title": "';
$outstr .= $title;
$outstr .= '", "msg":"';
$outstr .= $msg;
$outstr .= '" }]';
echo($outstr);
?>
Найти пользователя по имени (myAngularPostV5.php)
<?php
//if($_SERVER['HTTP_ORIGIN'] == "http://localhost:4200")
header('Access-Control-Allow-Origin: http://localhost:4200');
header("Access-Control-Allow-Headers: *");
header('Content-type: application/x-www-form-urlencoded; charset=UTF-8');
header('Access-Control-Allow-Methods: POST');
$data = json_decode(file_get_contents("php://input"));
$name = $data->name;
$users = Array();
$users[] = Array ("id"=> 1111, "name"=> "Bob", "title"=> "Manager", "msg"=> "CEO");
$users[] = Array("id"=> 222, "name"=> "Nik", "title"=> "Sales", "msg"=> "Corporate sales dept");
$users[] = Array("id"=> 4444, "name"=> "Anna", "title"=> "Technician", "msg"=> "Network support team");
$users[] = Array("id"=> 5, "name"=> "Haim", "title"=> "HR", "msg"=> "Human resource");
$users[] = Array("id"=> 76, "name"=> "Ronald", "title"=> "CA", "msg"=> "Accounting") ;
foreach($users as $key => $user){
if($user['name'] == $name){
$outstr = '[{ ';
$outstr .= '"id": "';
$outstr .= $user['id'];
$outstr .= '", "name": "';
$outstr .= $user['name'];
$outstr .= '", "title": "';
$outstr .= $user['title'];
$outstr .= '", "msg": "';
$outstr .= $user['msg'];
$outstr .= '" }]';
}
}
error_log( $outstr);
echo($outstr);
?>
Асинхронный поиск по мере ввода имени
В этом примере в окне браузера (в поле INPUT ) вводится имя сотрудника. По мере ввода (событие - keyup ) имя пересылается по POST серверу и проверяется PHP программой на сервере. Если PHP не нашёл сотрудника по имени (ищем в массиве сотрудников), он выдаёт сообщение (также в формате JSON)
Сервис
import { Injectable, OnInit } from '@angular/core';
import { HttpClient, HttpHeaders} from '@angular/common/http';
import { MyPostInterface } from './my-post-interface';
import { PostOptionsInterface } from './post-options-interface';
@Injectable({
providedIn: 'root'
})
export class MyPostService {
constructor(private myHttp: HttpClient) { }
sendRequest() {
const myUrl = 'http://angularhttp/myAngularPostV4.php';
let myData = [];
this.myHttp.post(myUrl, {observe: 'body', responseType: 'json'})
.subscribe({
next: data => console.log('Server request: ' , myData.push(data)),
error: err => console.error('Error: ' + err),
complete: () => console.log('Complete'),});
return myData;
}
getSingleUser() {
const myUrl = 'http://angularhttp/myAngularPostV5.php';
const myHeaders = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
let myData = [];
this.myHttp.post(myUrl, {name : 'Anna'}, {headers: myHeaders, observe: 'body', responseType: 'json'})
.subscribe({
next: data => console.log('Server request: ' , myData.push(data)),
error: err => console.error('Error: ' + err),
complete: () => console.log('Complete'),});
return myData;
}
findUser(userName){
const httpHdr = new HttpHeaders().set('Content-Type', 'application/x-www-form-urlencoded; charset=UTF-8');
const postUrl = 'http://angularhttp/myAngularPostV6.php';
const postBody = {name : userName};
let myData = [];
this.myHttp.post(postUrl, postBody, { headers: httpHdr, observe: 'body', responseType: 'json' })
.subscribe({
next: data => console.log('Server requested: ' , myData.push(data)),
error: err => console.error('Error: ' + err),
complete: () => console.log('Complete'),});
return myData;
}
}
Компонент
import { Component, OnInit } from '@angular/core';
import { MyPostService } from '../my-post.service';
@Component({
selector: 'app-my-post',
templateUrl: './my-post.component.html',
styleUrls: ['./my-post.component.css']
})
export class MyPostComponent implements OnInit {
allUsers = [];
singleUser = [];
foundUser = [];
constructor(private connectToServer: MyPostService) { }
ngOnInit() { }
getAllData() {
this.allUsers = this.connectToServer.sendRequest();
}
getSingleUser() {
this.singleUser = this.connectToServer.getSingleUser();
}
findUser(evnt){
console.log(evnt.target.value);
this.foundUser = this.connectToServer.findUser(evnt.target.value);
}
removeHint(evnt){
evnt.target.value = '';
evnt.target.select();
}
}
HTML - шаблон компонента
<h1>POST test component</h1>
<hr>
<button class='testbutton' (click)='getAllData()'>Request all users data from server</button>
<table>
<tr>
<th>ID</th>
<th>Name</th>
<th>Position</th>
<th>Remarks</th>
</tr>
<tr *ngFor='let str of allUsers[0]'>
<td>{{str['id']}}</td>
<td>{{str['name']}}</td>
<td>{{str['title']}}</td>
<td>{{str['msg']}}</td>
</tr>
</table>
<hr>
<button class='testbutton' (click)='getSingleUser()'>Get data of user: Anna</button>
<table>
<tr>
<th>ID</th>
<th>Name</th>
<th>Position</th>
<th>Remarks</th>
</tr>
<tr *ngFor='let str of singleUser[0]'>
<td>{{str['id']}}</td>
<td>{{str['name']}}</td>
<td>{{str['title']}}</td>
<td>{{str['msg']}}</td>
</tr>
</table>
<hr>
<input type='text' (keyup)='findUser($event)' (mouseenter)='removeHint($event); ' name='' value='Type case-sensitive user name here ...'>
<table>
<tr>
<th>ID</th>
<th>Name</th>
<th>Position</th>
<th>Remarks</th>
</tr>
<tr *ngFor='let str of foundUser[0]'>
<td colspan=4 *ngIf="str['id'] == 0; else found">{{str['name']}} {{str['title']}} {{str['msg']}}</td>
<ng-template #found>
<td>{{str['id']}}</td>
<td>{{str['name']}}</td>
<td>{{str['title']}}</td>
<td>{{str['msg']}}</td>
</ng-template>
</tr>
</table>
<hr>
CSS - стили компонента
BUTTON,
INPUT {
margin: 10px 0px;
}
INPUT {
width: 98.5%;
padding: 5px;
background-color: #EFEFEF;
}
TABLE {
border-collapse: collapse;
width: 100%;
}
TABLE TH {
color: red;
font-size: 1.2rem;
}
TABLE TH,
TABLE TD {
border: 1px solid lightgray;
padding: 5px;
}
.testbutton {
color: #FFF;
text-shadow: 1px 1px 0px #7CACDE;
box-shadow: 1px 1px 1px #BEE2F9;
padding: 10px 25px;
border-radius: 10px;
border: 2px solid #3866A3;
background: #63B8EE;
background: linear-gradient(to bottom, #63B8EE, #468CCF);
}
.testbutton:hover {
color: #F00;
background: #468CCF;
background: linear-gradient(to bottom, #468CCF, #63B8EE);
}
app.module.ts
import { BrowserModule } from '@angular/platform-browser';
import { NgModule } from '@angular/core';
import { AppComponent } from './app.component';
import { HttpClientModule } from '@angular/common/http'
import { MyPostService } from './my-post.service';
import { MyPostComponent } from './my-post/my-post.component';
@NgModule({
declarations: [
AppComponent,
MyPostComponent
],
imports: [
BrowserModule,
HttpClientModule
],
providers: [MyPostService],
bootstrap: [AppComponent]
})
export class AppModule { }
Интерфес - структура данных: my-post-interface.ts
export interface MyPostInterface {
id: number;
name: string;
title: string;
msg: string;
}
Server side: PHP - ищет сотрудника по имени (http://angularhttp/myAngularPostV6.php)
<?php
// if($_SERVER['HTTP_ORIGIN'] == "http://localhost:4200")
header('Access-Control-Allow-Origin: http://localhost:4200');
header('Content-type: application/x-www-form-urlencoded; charset=UTF-8');
header('Access-Control-Allow-Methods: POST');
$data = json_decode(file_get_contents("php://input"));
$name = $data->name;
$users = [];
$users[] = ["id"=> 1111, "name"=> "Bob", "title"=> "Manager", "msg"=> "CEO"];
$users[] = ["id"=> 222, "name"=> "Nik", "title"=> "Sales", "msg"=> "Corporate sales dept"];
$users[] = ["id"=> 4444, "name"=> "Anna", "title"=> "Technician", "msg"=> "Network support team"];
$users[] = ["id"=> 5, "name"=> "Haim", "title"=> "HR", "msg"=> "Human resource"];
$users[] = ["id"=> 76, "name"=> "Ronald", "title"=> "CA", "msg"=> "Accounting"] ;
$outstr = '[{ "id":"00000", "name":"User", "title":"not", "msg":"found" }]';
foreach($users as $key => $user){
if($user['name'] == $name){
$outstr = '[{ ';
$outstr .= '"id": ';
$outstr .= $user['id'];
$outstr .= ', "name": "';
$outstr .= $user['name'];
$outstr .= '", "title": "';
$outstr .= $user['title'];
$outstr .= '", "msg": "';
$outstr .= $user['msg'];
$outstr .= '" }]';
}
}
error_log($name);
error_log( $outstr);
echo($outstr);
?>
Server side: PHP выводит всех сотрудников ((http://angularhttp/myAngularPostV4.php))
<?php
header('Access-Control-Allow-Origin: http://localhost:4200');
header('Content-type: application/x-www-form-urlencoded; charset=UTF-8');
header("Access-Control-Allow-Headers: *");
header('Access-Control-Allow-Methods: POST');
$users = [];
$users[] = ["id"=> 1111, "name"=> "Bob", "title"=> "Manager", "msg"=> "CEO"];
$users[] = ["id"=> 222, "name"=> "Nik", "title"=> "Sales", "msg"=> "Corporate sales dept"];
$users[] = ["id"=> 4444, "name"=> "Anna", "title"=> "Technician", "msg"=> "Network support team"];
$users[] = ["id"=> 5, "name"=> "Haim", "title"=> "HR", "msg"=> "Human resource"];
$users[] = ["id"=> 76, "name"=> "Ronald", "title"=> "CA", "msg"=> "Accounting"] ;
$outstr = json_encode($users, JSON_PRETTY_PRINT);
echo($outstr);
?>
Результат - вывели всех сотрудников
Результат при начале набора в поле ввода
Результат - нашлось имя
PHP - error log (при каждом событии keyup PHP получает имя и пишет для отладки в error log полученное имя и строку для отправки в Angular ):
[01-Jun-2018 15:43:53 UTC] R
[01-Jun-2018 15:43:53 UTC] [{ "id":"00000", "name":"User", "title":"not", "msg":"found" }]
[01-Jun-2018 15:43:53 UTC] R
[01-Jun-2018 15:43:53 UTC] [{ "id":"00000", "name":"User", "title":"not", "msg":"found" }]
[01-Jun-2018 15:43:54 UTC] Ron
[01-Jun-2018 15:43:54 UTC] [{ "id":"00000", "name":"User", "title":"not", "msg":"found" }]
[01-Jun-2018 15:43:54 UTC] Ron
[01-Jun-2018 15:43:54 UTC] [{ "id":"00000", "name":"User", "title":"not", "msg":"found" }]
[01-Jun-2018 15:43:54 UTC] Rona
[01-Jun-2018 15:43:54 UTC] [{ "id":"00000", "name":"User", "title":"not", "msg":"found" }]
[01-Jun-2018 15:43:55 UTC] Ronal
[01-Jun-2018 15:43:55 UTC] [{ "id":"00000", "name":"User", "title":"not", "msg":"found" }]
[01-Jun-2018 15:43:55 UTC] Ronald
[01-Jun-2018 15:43:55 UTC] [{ "id": 76, "name": "Ronald", "title": "CA", "msg": "Accounting" }]