mirror of
https://github.com/Polymer/polymer.git
synced 2025-02-25 18:55:30 -06:00
update based on pull request comments:
- separate g-xhr to a component (component-as-module-pattern) - dispatch Events instead - add jsdoc to public methods - update comment - use classList.enable - use handlers="click: clickHandler" instead of experimental event binding
This commit is contained in:
@@ -7,76 +7,25 @@
|
|||||||
-->
|
-->
|
||||||
<element name="g-ajax" attributes="url, handleAs, params">
|
<element name="g-ajax" attributes="url, handleAs, params">
|
||||||
<link rel="components" href="g-component.html">
|
<link rel="components" href="g-component.html">
|
||||||
|
<link rel="components" href="g-xhr.html">
|
||||||
<template>
|
<template>
|
||||||
|
<g-xhr id="xhr"></g-xhr>
|
||||||
<content></content>
|
<content></content>
|
||||||
</template>
|
</template>
|
||||||
<script>
|
<script>
|
||||||
var xhr = {
|
|
||||||
request: function(inOptions) {
|
|
||||||
var transport = this.getTransport();
|
|
||||||
var url = inOptions.url;
|
|
||||||
var method = inOptions.method || 'GET';
|
|
||||||
var async = !inOptions.sync;
|
|
||||||
var params = this.toQueryString(inOptions.params);
|
|
||||||
if (params && method == 'GET') {
|
|
||||||
url += (url.indexOf('?') > 0 ? '&' : '?') + params;
|
|
||||||
}
|
|
||||||
transport.open(method, url, async);
|
|
||||||
this.makeReadyStateHandler(transport, inOptions.callback);
|
|
||||||
this.setRequestHeaders(inOptions.headers);
|
|
||||||
transport.send(method == 'POST' ? (inOptions.body || params) : null);
|
|
||||||
if (!async) {
|
|
||||||
transport.onreadystatechange(transport);
|
|
||||||
}
|
|
||||||
return transport;
|
|
||||||
},
|
|
||||||
getTransport: function() {
|
|
||||||
try {
|
|
||||||
return new XMLHttpRequest();
|
|
||||||
} catch (e) {}
|
|
||||||
try {
|
|
||||||
return new ActiveXObject('Msxml2.XMLHTTP');
|
|
||||||
} catch (e) {}
|
|
||||||
try {
|
|
||||||
return new ActiveXObject('Microsoft.XMLHTTP');
|
|
||||||
} catch (e) {}
|
|
||||||
return false;
|
|
||||||
},
|
|
||||||
makeReadyStateHandler: function(inXhr, inCallback) {
|
|
||||||
inXhr.onreadystatechange = function() {
|
|
||||||
if (inXhr.readyState == 4) {
|
|
||||||
inCallback && inCallback.apply(null, [inXhr.responseText, inXhr]);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
},
|
|
||||||
setRequestHeaders: function(inXhr, inHeaders) {
|
|
||||||
if (inHeaders) {
|
|
||||||
for (var name in inHeaders) {
|
|
||||||
xhr.setRequestHeader(name, inHeaders[name]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
toQueryString: function(inParams) {
|
|
||||||
var r = [];
|
|
||||||
for (var n in inParams) {
|
|
||||||
var v = inParams[n];
|
|
||||||
n = encodeURIComponent(n);
|
|
||||||
r.push(v === undefined || v === null ? n : (n + '=' + encodeURIComponent(v)));
|
|
||||||
}
|
|
||||||
return r.join('&');
|
|
||||||
}
|
|
||||||
};
|
|
||||||
this.component({
|
this.component({
|
||||||
created: function(inSuper) {
|
created: function(inSuper) {
|
||||||
this.context = this.context || window;
|
|
||||||
if (this.getAttribute('autogo')) {
|
if (this.getAttribute('autogo')) {
|
||||||
this.go();
|
this.go();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
prototype: {
|
prototype: {
|
||||||
|
/**
|
||||||
|
* Performs an Ajax request to the url specified.
|
||||||
|
*/
|
||||||
go: function() {
|
go: function() {
|
||||||
var params = JSON.parse(this.params);
|
var params = JSON.parse(this.params);
|
||||||
return xhr.request({url: this.url, callback: this.receive.bind(this), params: params});
|
return this.$.xhr.request({url: this.url, callback: this.receive.bind(this), params: params});
|
||||||
},
|
},
|
||||||
receive: function(inResponse, inXhr) {
|
receive: function(inResponse, inXhr) {
|
||||||
if (this.isSuccess(inXhr)) {
|
if (this.isSuccess(inXhr)) {
|
||||||
@@ -90,21 +39,23 @@
|
|||||||
var status = inXhr.status || 0;
|
var status = inXhr.status || 0;
|
||||||
return !status || (status >= 200 && status < 300);
|
return !status || (status >= 200 && status < 300);
|
||||||
},
|
},
|
||||||
fire: function(inMethod, inArgs) {
|
dispatchAjaxEvent: function(inType, inResponse, inXhr) {
|
||||||
var fn = this.context[this.getAttribute(inMethod)];
|
this.dispatchEvent(new CustomEvent(inType,
|
||||||
fn && fn.apply(this.context, inArgs);
|
{detail: {response: inResponse, xhr: inXhr}}));
|
||||||
},
|
},
|
||||||
response: function(inXhr) {
|
response: function(inXhr) {
|
||||||
var response = this.evalResponse(inXhr);
|
var response = this.evalResponse(inXhr);
|
||||||
this.fire('onresponse', [response, inXhr]);
|
this.dispatchAjaxEvent('response', response, inXhr);
|
||||||
|
// Here we want to expose the response as a model so that it can be
|
||||||
|
// consumed by other components.
|
||||||
this.model = this.model || {};
|
this.model = this.model || {};
|
||||||
this.model.response = response;
|
this.model.response = response;
|
||||||
},
|
},
|
||||||
error: function(inXhr) {
|
error: function(inXhr) {
|
||||||
this.fire('onerror', [inXhr.status + ': ' + inXhr.responseText, inXhr]);
|
this.dispatchAjaxEvent('error', inXhr.status + ': ' + inXhr.responseText, inXhr);
|
||||||
},
|
},
|
||||||
complete: function(inXhr) {
|
complete: function(inXhr) {
|
||||||
this.fire('oncomplete', [inXhr]);
|
this.dispatchAjaxEvent('complete', inXhr.status, inXhr);
|
||||||
},
|
},
|
||||||
evalResponse: function(inXhr) {
|
evalResponse: function(inXhr) {
|
||||||
return this[(this.handleAs || 'text') + 'Handler'](inXhr);
|
return this[(this.handleAs || 'text') + 'Handler'](inXhr);
|
||||||
|
|||||||
@@ -5,11 +5,11 @@
|
|||||||
* license that can be found in the LICENSE file.
|
* license that can be found in the LICENSE file.
|
||||||
*/
|
*/
|
||||||
-->
|
-->
|
||||||
<element name="g-togglebutton" attributes="value">
|
<element name="g-togglebutton" attributes="value" handlers="click: clickHandler">
|
||||||
<link rel="components" href="g-component.html">
|
<link rel="components" href="g-component.html">
|
||||||
<link rel="stylesheet" href="css/g-togglebutton.css" />
|
<link rel="stylesheet" href="css/g-togglebutton.css" />
|
||||||
<template>
|
<template>
|
||||||
<div id="toggle" class="toggle" onclick="x('clickHandler')">
|
<div id="toggle" class="toggle">
|
||||||
<span class="on">ON</span>
|
<span class="on">ON</span>
|
||||||
<span class="off">OFF</span>
|
<span class="off">OFF</span>
|
||||||
<span class="thumb"></span>
|
<span class="thumb"></span>
|
||||||
@@ -22,12 +22,12 @@
|
|||||||
},
|
},
|
||||||
prototype: {
|
prototype: {
|
||||||
valueAttributeChanged: function() {
|
valueAttributeChanged: function() {
|
||||||
this.$.toggle.classList[this.trueValue() ? 'add' : 'remove']('on');
|
this.$.toggle.classList.enable('on', this.trueValue());
|
||||||
},
|
},
|
||||||
clickHandler: function() {
|
clickHandler: function() {
|
||||||
this.value = !this.trueValue();
|
this.value = !this.trueValue();
|
||||||
},
|
},
|
||||||
// note: should base component auto-convert string value to boolean?
|
// TODO(ffu): remove this when base component handles auto-converting string value to boolean
|
||||||
trueValue: function() {
|
trueValue: function() {
|
||||||
return this.value != 'false' && Boolean(this.value);
|
return this.value != 'false' && Boolean(this.value);
|
||||||
}
|
}
|
||||||
|
|||||||
90
src/g-xhr.html
Normal file
90
src/g-xhr.html
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
<!--
|
||||||
|
/*
|
||||||
|
* Copyright 2012 The Toolkitchen Authors. All rights reserved.
|
||||||
|
* Use of this source code is governed by a BSD-style
|
||||||
|
* license that can be found in the LICENSE file.
|
||||||
|
*/
|
||||||
|
-->
|
||||||
|
<element name="g-xhr">
|
||||||
|
<link rel="components" href="g-component.html">
|
||||||
|
<template>
|
||||||
|
<style>
|
||||||
|
@host {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</template>
|
||||||
|
<script>
|
||||||
|
this.component({
|
||||||
|
prototype: {
|
||||||
|
/**
|
||||||
|
* Sends a HTTP request to the server and returns the XHR object.
|
||||||
|
*
|
||||||
|
* @param inOptions A set of key/value pairs that configure the request.
|
||||||
|
* @param inOptions.url The url to which the request is sent.
|
||||||
|
* @param inOptions.method The HTTP method to use, default is GET.
|
||||||
|
* @param inOptions.sync By default, all requests are sent asynchronously.
|
||||||
|
* To send synchronous requests, set to true.
|
||||||
|
* @param inOptions.params Data to be sent to the server.
|
||||||
|
* @param inOptions.body The content for the request body for POST method.
|
||||||
|
* @param inOptions.headers HTTP request headers.
|
||||||
|
* @param inOptions.callback Called when request is completed.
|
||||||
|
* @returns XHR object.
|
||||||
|
*/
|
||||||
|
request: function(inOptions) {
|
||||||
|
var transport = this.getTransport();
|
||||||
|
var url = inOptions.url;
|
||||||
|
var method = inOptions.method || 'GET';
|
||||||
|
var async = !inOptions.sync;
|
||||||
|
var params = this.toQueryString(inOptions.params);
|
||||||
|
if (params && method == 'GET') {
|
||||||
|
url += (url.indexOf('?') > 0 ? '&' : '?') + params;
|
||||||
|
}
|
||||||
|
transport.open(method, url, async);
|
||||||
|
this.makeReadyStateHandler(transport, inOptions.callback);
|
||||||
|
this.setRequestHeaders(inOptions.headers);
|
||||||
|
transport.send(method == 'POST' ? (inOptions.body || params) : null);
|
||||||
|
if (!async) {
|
||||||
|
transport.onreadystatechange(transport);
|
||||||
|
}
|
||||||
|
return transport;
|
||||||
|
},
|
||||||
|
getTransport: function() {
|
||||||
|
try {
|
||||||
|
return new XMLHttpRequest();
|
||||||
|
} catch (e) {}
|
||||||
|
try {
|
||||||
|
return new ActiveXObject('Msxml2.XMLHTTP');
|
||||||
|
} catch (e) {}
|
||||||
|
try {
|
||||||
|
return new ActiveXObject('Microsoft.XMLHTTP');
|
||||||
|
} catch (e) {}
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
makeReadyStateHandler: function(inXhr, inCallback) {
|
||||||
|
inXhr.onreadystatechange = function() {
|
||||||
|
if (inXhr.readyState == 4) {
|
||||||
|
inCallback && inCallback.apply(null, [inXhr.responseText, inXhr]);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
},
|
||||||
|
setRequestHeaders: function(inXhr, inHeaders) {
|
||||||
|
if (inHeaders) {
|
||||||
|
for (var name in inHeaders) {
|
||||||
|
xhr.setRequestHeader(name, inHeaders[name]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
toQueryString: function(inParams) {
|
||||||
|
var r = [];
|
||||||
|
for (var n in inParams) {
|
||||||
|
var v = inParams[n];
|
||||||
|
n = encodeURIComponent(n);
|
||||||
|
r.push(v === undefined || v === null ? n : (n + '=' + encodeURIComponent(v)));
|
||||||
|
}
|
||||||
|
return r.join('&');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</element>
|
||||||
Reference in New Issue
Block a user