0

使用 Polymer 1.0,我设置了一个铁表格来提交一个简单的联系表格。这个想法是使用 PHP 将表单提交到数据库表,然后在不刷新的情况下将来自 PHP 端的响应显示到浏览器中 - 典型的 AJAX。不过,我对 Polymer 环境很感兴趣 - 似乎应该有正确的方法来做到这一点,但数小时的搜索和修补并没有取得成果。

我确实使用 Polymer Starter Kit (lite) 启动了这个项目,它使用脚本 (app.js) 添加事件侦听器等。到目前为止,我还没有破坏该功能,尽管文档中的所有示例都没有这样做,所以它使事情变得更加复杂,因为我仍然习惯于 Polymer。

这是我到目前为止所得到的。非常感谢您提供的任何建议。

索引.html

<!-- this is where the output should be displayed -->
<div id="output"></div>

<!-- this is the web form -->
<form is="iron-form" id="contactus-form" method="post" action="/">
<input type="hidden" name="action" value="contactus-form">
<paper-input id="contactus-field-Name" name="Name" label="Name" value="test"></paper-input>
<paper-button onclick="submitHandler(event)">Send</paper-button>
</form>

...

<script src="script/app.js"></script>
<script>
function submitHandler(event) {
    Polymer.dom(event).localTarget.parentElement.submit();
    }
</script>

应用程序.js

(function(document) {
  'use strict';

  addEventListener('iron-form-submit', function(e) {

    // this works and displays the POSTed values in the browser
    document.querySelector('#output').innerHTML = JSON.stringify(e.detail);

    // I'm looking for a way to first submit this data through PHP and 
    // display the output of that process in the #output div rather than the 
    // raw form input itself.

    }
})(document);

失败的方法1

我尝试将 iron-ajax 元素添加到index.html并从app.js引用它,如下所示。不幸的是,当它尝试添加事件监听器时,整个应用程序崩溃了。这似乎很奇怪,因为 app.js 中还有许多其他部分以相同的方式添加事件侦听器。

索引.html

<iron-ajax id="contactus-output" url="/form/contact.php" params="" handle-as="json"></iron-ajax>
<!-- same form as before goes here -->

应用程序.js

var coutput = document.querySelector('#contactus-output');
coutput.addEventListener('response', function() {
    // nothing fancy here yet, just trying to see if I can do this
    document.querySelector('#output').innerHTML = 'hello world';
    }

失败的方法 2

在 SO 上找到了这个答案,并决定尝试这个iron-form-response活动。我现在收到的输出是[object HTMLElement],这至少是一些东西,尽管我不确定它是否真的有效。

其他一切都保持不变,我将表单的目标更改为指向我的 php 脚本,然后将 app.js 中的内容替换为以下内容:

应用程序.js

addEventListener('iron-form-response', function(e) {
  document.querySelector('#output').innerHTML = e.detail;
});

我离得更近了吗?

不放弃

使用我上面第二个失败的方法,iron-form 似乎正在发出请求,因为当我监听 'iron-form-response' 事件时,它确实触发了。

但是,唯一返回的是[object HTMLElement]- 不知道该怎么做。我尝试吐出它的一些属性(如 developer.mozilla.org 上记录的 - .title.properties.style等),但它们似乎是空的。Iron-form 真的返回一个 HTMLElement 对象还是这是一个错误?我认为它会从我提交表单的 PHP 脚本返回结果,就像普通的XMLHttpRequest. 如果铁形式以某种方式将其压缩成一个物体,有没有办法再次将其拉出?

TL;博士

我认为这整件事归结为:iron-form-request当我的 Iron-form 位于 index.html 并且 index.html 由 app.js 引导时,我如何正确添加事件监听器(for ),就像 Polymer 中默认发生的那样1.0 入门套件?

进一步简化:当我不创建元素(仅使用它)时,如何将事件侦听器正确添加到 Polymer 的影子 DOM?

漏洞?

在user2422321下面精彩回答的帮助下,正在执行iron-request并收到成功的iron-request响应。但是,它的“response”属性返回 NULL,即使“succeeded”返回 true,也没有错误,并且 XHR 完全解析。“get”和“post”方法都用相同的 NULL 结果进行了测试。

我看到 10 天前在 GitHub 上准确记录了一个与这些症状相匹配的错误,尽管它没有引起太多关注:Issue 83。这是不幸的,但它似乎是一个错误。在修复元件本身之前,我不相信有任何方法可以使其正常工作。

Iron-REQUEST 想看什么?!

当我进一步探索时,我发现即使 XHR 直接返回“null”,即使它的 responseURL 正确且 statusText 为“OK”。我开始怀疑我正在尝试运行的实际 PHP 脚本(目前只输出“Hello World”)是否有问题。

是否iron-form-request期望结果中有某种格式或数据类型?我尝试添加header('Content-Type: text/plain');到我的 PHP 文件,然后尝试将其格式化为经过验证的 JSON 字符串,但响应仍然是null. 似乎没有任何作用。

老派直接XMLHttpRequest的工作正常......在提交请求之前,铁形式是否畸形?

我确实设置了一个处理程序来捕获 iron-form-error 但没有收到任何内容。根据回复中的每一条信息,世界上的一切都是完美的。只是......空响应。一遍又一遍……这真是令人难以置信的沮丧。

解决方案!(有点)

好吧,我已经够绝望了,我开始翻阅 Iron 源代码本身。目前看来, Iron-form 仍然有些小故障,并且仅在响应格式正确的 json 时才返回内容。在iron-request.html中,它似乎允许以下类型,但不要上当。我只能让json工作 - 我认为其余的最终都会符合要求。

  • json(应用程序/json)
  • 文本(文本/纯文本)
  • html (文本/html)
  • xml(应用程序/xml)
  • arraybuffer(应用程序/八位字节流)

因此,目前,我们需要将响应格式化为 JSON 并包含一个 DOCTYPE 声明以进行匹配。

就我而言,这看起来像这样(感谢 user2422321 对我的帮助很大):

索引.php

<div id="output">{{myOutput}}</div>

<form is="iron-form" id="contactUsForm" method="get" action="/contactus.php" on-iron-form-response="_onResponseRetrieved">
<paper-input id="Name" name="Name" value="text" label="Name"></paper-input>
<paper-button id="contactSubmitButton" on-tap="_submitHandler">Submit</paper-button>
</form>

应用程序.js

(function(document) {
...
app._onResponseRetrieved = function(e) {
  this.myOutput = e.detail;
  console.log(e);
};
app._submitHandler = function(e) {
  this.$.contactUsForm.submit();
});
...
})(document);

最后,这是最重要的拼图。我以前没有考虑过这个文件输出的内容非常重要,因为直接 XMLHttpRequests 返回文件吐出的任何内容。

联系我们.php

<?php
// This is the line I added
header('Content-Type: application/json');
// Actual Code goes here
// Then make sure to wrap your final output in JSON
echo '{"test":"this is some test json to try"}';

有了所有这些部分,它就可以工作并包含我们从contactus.phpe.detail.response回显的 JSON 响应。

4

2 回答 2

1

不太确定我是否理解什么是行不通的,但这是我认为应该以“纯”聚合物方式完成的方式(我的意思是尽可能少的 Javascript)。

<div id="output">{{myOutput}}</div>

<!-- this is the web form -->
<form is="iron-form" id="contactUsForm" method="post" action="/" on-iron-form-response="_onResponseRetrieved">
   <input type="hidden" name="action" value="contactUsForm">
   <paper-input id="contactus-field-Name" name="Name" label="Name" value="test"></paper-input>
   <paper-button on-tap="_submitHandler">Send</paper-button>
</form>


_onResponseRetrieved: function(e)
{
    //I'm not 100% sure what e.detail actually contain, but the value your looking for should be inside there somewhere
    this.myOutput = e.detail; 
}
_submitHandler: function(e)
{
    //Note that I renamed the id of your form :)
    this.$.contactUsForm.submit();
}

我还看到了onclick应该on-tap让它在移动设备上正常工作的建议,因此我改变了它。

一旦您收到来自服务器的响应,UI 现在应该会更新!

-

编辑:

因为您使用的是 Polymer Starter Kit,它在内部执行一些主要逻辑,所以index.html有些事情有点不同。在 Polymer 文档中,通常会给出一些示例,其中显示了元素内部的一些代码,而它们index.html看起来或功能并不完全像一个元素,这确实会令人困惑。在我自己的项目中,我实际上跳过了里面的所有逻辑,index.html因为我认为它看起来很混乱和复杂,但是当回头看时,它并不是那么奇怪(在我看来仍然不漂亮)。我不确定这一点,但是index.html如果您想将代码(javascript)和外观(html/css)分开,那么设置的方式可能是设置自定义元素的方式。

所以要让你的代码工作:在app.js你看到这一行:

var app = document.querySelector('#app');

您可以将app变量视为自定义元素。在index.html你可以看到这一行,它有点说:“如果你点击我,我将调用onDataRouteClick元素中的方法app”:

<a data-route="home" href="/" on-click="onDataRouteClick">

那么,为什么它会调用元素上的方法app呢?那是因为上面的行是以下代码的子行:(<template is="dom-bind" id="app">注意 id 与此无关,除了我们通过该 id 在 Javascript 中定位它,所以当我谈论app对象时,我指的是 Javascript 中的那个) .

在内部,我们可以通过执行以下操作app.js来定义调用时会发生什么:onDataRouteClick

   app.onDataRouteClick = function() {
      var drawerPanel = document.querySelector('#paperDrawerPanel');
      if (drawerPanel.narrow) {
         drawerPanel.closeDrawer();
      }
   };

我不知道为什么,但他们一直使用这条线来查找对象:

var drawerPanel = document.querySelector('#paperDrawerPanel');

但是当你在你的范围内时,app你实际上可以使用它,我认为它更像是 Polymer ish

var drawerPanel = this.$.paperDrawerPanel;

-

抱歉,如果您已经知道这一切,那么现在我们如何让您的代码正常工作?

在里面app.js添加这个:

app._onResponseRetrieved = function(e)
{
    //I'm not 100% sure what e.detail actually contain, but the value your looking for should be inside there somewhere
    this.myOutput = e.detail;
    console.log(e); //Check the console to see exactly where the data is
};
app._submitHandler = function(e)
{
    //Note that I renamed the id of your form :)
    //We are in the scope of 'app' therefore we can write this
    this.$.contactUsForm.submit();
};

而且index.html你会有类似的东西(显然它应该在template元素内):

<div id="output">{{myOutput}}</div>

<!-- this is the web form -->
<form is="iron-form" id="contactUsForm" method="post" action="/" on-iron-form-response="_onResponseRetrieved">
   <input type="hidden" name="action" value="contactUsForm">
   <paper-input id="contactus-field-Name" name="Name" label="Name" value="test"></paper-input>
   <paper-button on-tap="_submitHandler">Send</paper-button>
</form>
于 2015-11-15T14:23:32.663 回答
1

我正在使用 Polymer 2,我遇到了类似的问题。

这是我的元素文件:

<template is="dom-bind">

    <iron-ajax
            auto
            id="ajax"
            url="test.php"
            handle-as="json"
            method="POST"
            body='{"email":"ankita@gmail.com", "lastlogin":"Feb 21st 2016", "notifications":6}'
            content-type = "application/json"
            last-response="{{responseObject}}" >
    </iron-ajax>

    <login-element details="[[responseObject]]"></login-element>
</template>

login-element.html 看起来像这样:

<dom-module id="login-element" >
<template>

    <!--<form action="test1.php" method="post"  enctype='application/json'>-->
        <!--Name: <input type="text" name="name"><br>-->
        <!--E-mail: <input type="text" name="email"><br>-->
        <!--<input type="submit" onclick="submitForm()">-->
    <!--</form>-->

    <h2>{{details.email}}</h2>

</template>

<script>
    Polymer({
        is:"login-element",
        properties:{
            details:Object
        }
    });

</script>

和test.php

<?php
$data = json_decode(file_get_contents('php://input'), true);
echo json_encode($data);
exit;
于 2017-03-17T11:24:10.760 回答