2017-06-08 63 views
0

我创建了一个表单,我希望用户可以选择他们想要的房间等等。如果我将其作为下拉菜单或输入类型来输入信息,则通过PHP通过电子邮件提交。无法将隐藏的输入值从Angular传递到PHP

但是,如果我改变输入类型为“隐藏”,价值完全消失,我在控制台中看到的是这样的:

<input _ngcontent-c4 name="room" type="hidden" value class="ng-untouched ng-pristine ng-valid"> 

然后,在网络中,没有出现一个对象“房间”。 (注:其他物体确实出现。)

然后,如果我只是简单地将样式更改为“display:none;”并将值=“ChosenRoom”,电子邮件中不发送任何内容。实际上,尽管在控制台上显示得很清楚,但因为

<input _ngcontent-c4 name="room" style="display: none;" type="text" value="ChosenRoom" class="ng-untouched ng-pristine ng-valid"> 

该对象没有显示在网络中。

任何想法可能是什么问题呢?

CODE:

(我有一个基本的Plunker贴吧,以及:http://embed.plnkr.co/uUhPrStdw4kDhaus2xfO/

这一个工程,但用户在表单房间名键入:

HTML(注意:我遗漏了表格的其余代码,假设它与这种情况无关。如果您认为这有帮助,我很乐意将其发布。)

<form (submit)="sendEmail(message)" #f="ngForm"> 
    <input type="text" name="room" [(ngModel)]="message.room" #room="ngModel"> 
    <button type="submit" [disabled]="f.invalid" *ngIf="!f.submitted"> 
</form> 

HTML - 此控件不显示值。

<form (submit)="sendEmail(message)" #f="ngForm"> 
    <input type="hidden" name="room" [(ngModel)]="message.room" #room="ngModel" value="ThisRoom"> 
    <button type="submit" [disabled]="f.invalid" *ngIf="!f.submitted"> 
</form> 

HTML - 这一个显示在控制台中值,但不显示在网络上的任何对象。

<form (submit)="sendEmail(message)" #f="ngForm"> 
    <input type="text" style="display: none;" name="room" [(ngModel)]="message.room" #room="ngModel" value="ThisRoom"> 
    <button type="submit" [disabled]="f.invalid" *ngIf="!f.submitted"> 
</form> 

打字稿:Contact.Service.TS

import { Injectable } from '@angular/core'; 
import { Http } from '@angular/http'; 
import { Observable } from 'rxjs/Observable'; 
import { Resolve } from '@angular/router'; 
import 'rxjs/add/operator/map'; 
import 'rxjs/add/operator/catch'; 

export interface IMessage { 
    name?: string, 
    email?: string, 
    room?: string, 
    daterange?: string, 
    message?: string 
} 

@Injectable() 
export class AppService { 
    private emailUrl = '/assets/email.php'; 

    constructor(private http: Http) { 

    } 

    sendEmail(message: IMessage): Observable<IMessage> | any { 
    return this.http.post(this.emailUrl, message) 
     .map(response => { 
     console.log('Sending email was successfull', response); 
     return response; 
     }) 
     .catch(error => { 
     console.log('Sending email got error', error); 
     return Observable.throw(error) 
     }) 
    } 
} 

PHP

<?php 

header('Content-type: application/json'); 

$errors = ''; 

if(empty($errors)) 
{ 

    $postdata = file_get_contents("php://input"); 
    $request = json_decode($postdata); 


    $from_email = '[email protected]'; 
    $message = $request->message; 
    $from_name = $request->name; 

    $to_email = "[email protected]"; 

    $contact = "<p><strong>Name:</strong> $from_name</p> 
       <p><strong>Email:</strong> $request->email</p> 
       <p><strong>Room:</strong> $request->room</p> 
       <p><strong>Dates:</strong> $request->daterange</p>"; 
    $content = "<p><strong>Message:</strong><p>$message</p>"; 




    $website = 'My Currently Not but soon to be Functioning Website'; 
    $email_subject = "$website: Received a message from $from_name"; 

    $email_body = '<html><body>'; 
    $email_body .= "$contact $content"; 
    $email_body .= '</body></html>'; 

    $headers .= "MIME-Version: 1.0\r\n"; 
    $headers .= "Content-Type: text/html; charset=ISO-8859-1\r\n"; 
    $headers .= "From: $from_email\n"; 
    $headers .= "Reply-To: $from_email"; 

    $result = mail($to_email,$email_subject,$email_body,$headers); 

    $response_array['status'] = 'success'; 
    $response_array['from'] = $from_email; 
    $response_array['result'] = $result; 

    echo json_encode($response_array); 

    header($response_array); 
    return $from_email; 
} else { 
    $response_array['status'] = 'error'; 
    echo json_encode($response_array); 
    header('Location: /error.html'); 
} 
?> 

我明白任何帮助或想法。

谢谢!

布拉德

+1

是否包含在Angular中的隐藏值?如果不是的话,你可以尝试在蹲点中重现问题,因为我可以在角码中包含隐藏的字段。 – Alex

+0

好主意@ AJT_82我已经添加了一个基本的Plunker的职位。我找到了一种避免隐藏领域问题的替代解决方案。所以,我不确定我是否可以实际做隐藏领域。 – AlmostPitt

+0

这与它实际上隐藏无关。 'ngModel'覆盖'value'。另外,由于你可以很好地从窗体中获得相同的对象,所以它没有真正具有双向绑定的意义:)另外,在这种情况下,我可能会建议一个模型驱动的窗体,隐藏的财产将很容易创建:)如果你想坚持模板驱动的形式,我建议你将默认值设置为'房间'而不是。 – Alex

回答

1

我已经找到了这个问题的一种解决方案。它完全避免了隐藏的领域,我仍然不确定他们是否存在问题。

工作液:

contact.component.html - 在这里,我避免了隐藏的输入和传递消息旁边的文本。要特别注意'这个特定的房间'

<form (submit)="sendEmail(message, 'This particular room')" #f="ngForm"> 
... 
</form> 

contact.component.ts - 要特别注意message.room =室;

import { Component, OnInit, HostBinding } from '@angular/core'; 
import { AppService, IMessage } from '../../contact/contact.service'; 

@Component({ 
    selector: 'app-contact', 
    templateUrl: './contact.component.html', 
    styleUrls: ['./contact.component.css'] 
}) 
export class TheensuiteComponent implements OnInit { 
    message: IMessage = {}; 

    constructor(private appService: AppService) { } 

    sendEmail(message: IMessage, room:string) { 
    message.room = room; 
    this.appService.sendEmail(message).subscribe(res => { 
     console.log('ContactComponent Success', res); 
    }, error => { 
     console.log('ContactComponent Error', error); 
    }) 
    } 

    ngOnInit() { 
    }; 
    } 
} 

其他一切留在同一(contact.service.ts和email.php)。

这当然是一个小小的破解。如果我想传递更多信息,这可能会很快导致混乱的代码。

0

首先,该值不加,是因为ngModel覆盖value,因此与隐藏的事实无关。其次,我建议你可能想在这里使用模型驱动的形式。有时模型驱动的形式是过度杀伤性的,但在这种情况下,我会使用一种。所以我想如果你想考虑的话,我会为你选择这个选项。

您需要导入ReactiveFormsModule并将其添加到您的ngModule中的imports数组中。然后导入以下到您的组件,并在构造函数中注入FormBuilder

import { FormBuilder, FormGroup, Validators } from '@angular/forms'; 

constructor(private fb: FormBuilder) {} 

然后建立与你想要的验证形式:

this.myForm = this.fb.group({ 
    room: ['theEnsuite'], 
    name: ['', Validators.required], 
    email: ['', [Validators.required, Validators.pattern('[a-z0-9._%+-][email protected][a-z0-9.-]+\.[a-z]{2,3}$']], 
    message: ['', [Validators.required, Validators.minLength(10)]] 
}) 

然后你就可以摆脱双的而不是使用窗体控件交换它。好的是,你不需要在模板中包含room。这是很好的已经坐在形式对象:)这里的name输入的错误消息的示例:

<input placeholder="Name" formControlName="name"> 
<div *ngIf="!myForm.get('name').valid && myForm.get('name').touched"> 
    <p>Please enter your name.</p> 
</div> 

当你提交表单你myForm.value为参数做到这一点。那么该对象与您的IMessage类型的对象相同,您可以直接使用此对象的post请求!

这里是上述的DEMO