热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

使用HTML5数据库和离线功能

愿文出处:http:www.ibm.comdeveloperworkscnwebwa-html5db提供离线数据编辑和数据同步化HTML5将扩展Web体验和业务线应用程序。有了离线
愿文出处: http://www.ibm.com/developerworks/cn/web/wa-html5db/


提供离线数据编辑和数据同步化

HTML5 将扩展 Web 体验和业务线应用程序。有了离线功能和本地持久存储特性,您不管是在线还是离线状态都可以交付同样丰富的用户体验,这些体验以前只可在专用的桌面应用程序开发框架中获得。在本文中,您将了解如何利用 HTML5 的离线功能和本地持久存储特性。示例应用程序说明了如何避免常见的问题。

简介

常用缩写词

  • CRUD:创建、读取、更新和删除
  • HTML:超文本标记语言
  • JSON:Javascript 对象表示法
  • LOB:业务线
  • UI:用户界面

HTML 版本 5 (HTML5) 并不期望在 2012 年之前获得万维网联盟 (W3C) 推荐。尽管 HTML5 不是官方标准,但 Web 浏览器供应商正在增加和营销 HTML5 特性。HTML5 正在为 Internet 网站和业务线 (LOB) 应用程序扩展 Web 体验。像 Amazon Kindle Cloud Reader 等许多网站已经开始使用 HTML5。有两个关键的 HTML5 特性会显著更改 LOB 应用程序:离线应用程序支持和本地持久存储。由于 HTML5 不是一个官方标准,所以浏览器支持是不一致的。

在本文中,您将了解由 HTML5 标准提供的有关离线应用程序支持和不同持久存储功能的信息。示例应用程序有助于说明这些特性。

示例应用程序

Contact Manager 示例应用程序专为管理联系信息(姓名、地址和电话号码)而提供的。它提供了一种在线模式、一种离线模式,以及一种简单的数据同步化功能,以使本地数据更改与切换到在线模式服务器实现同步。当处于离线状态时,数据于本地持久存储。应用程序支持在线和离线模式下的四个基本持久存储功能:创建、读取、更新和删除 (CRUD)。

架构

图 1 展示了 Contact Manager 应用程序架构的概述。服务器架构包括两个 servlet:业务服务和数据提供程序。用户界面包括一个单一的 HTML 文件、四个 Javascript 模块,以及一个 jQuery 库最新版本的外部引用。

图 1. 应用程序架构概述
该图显示了应用程序架构

数据模型

数据模型包括两个数据实体:联系人和状态,如 图 2 所示。联系人表包含实际的联系人数据;状态表包含状态选择列表的字典值。

图 2. 数据模型
该图显示了数据模型

服务器界面

服务器界面包含两个 servlet:ContactServlet 和 DictionaryServlet。表 1对 servlet 进行了总结。(servlet 的实现和相应业务服务与数据提供程序不在本文的讨论范围之内。)

表 1. servlet 摘要
Servlet 名称 操作 参数 描述
DictionaryServletcode> getstates N/A 以 Javascript 对象表示法
 (JSON) 格式返回一个状态
数组。
ContactServlet getallcontacts N/A 以 JSON 格式返回一个联系人
数组。
ContactServlet delete contactId:需要删除的联系人 ID。 删除指定的联系人记录;返回一
个 JSON 对象,并带有一个
Boolean 标志来表明操作是
否成功。
"{"result":
true/false"}
ContactServlet save
  • contactId:需要保存的联系人 ID。
  • (如果大于 0,
  • 则是一项更新操作。)
  • firstName:第一个名称字段的值。
  • lastName:最后一个名称字段的值。
  • street1:街道 1 字段的值。
  • street2:街道 2 字段的值。
  • city:城市字段的值。
  • state:状态字段的值。
  • zipCode:邮编字段的值。
返回一个带有 Boolean 标识的
 JSON 对象,用于表明操作是
否成功,是否是新的或更新的
联系人 ID。
"{"contactId":
,
"result": "}

调用服务器界面

清单 1 中的代码显示了如何对联系人 servlet 进行异步调用来检索存储于在线数据库中的联系人。代码使用了 jQuery getJSON 函数来调用联系人 servlet。

清单 1. 从服务器中检索联系人
function loadOnlineContacts() 
{
$('#contactList').empty();
$('#contactList').append('Loading contact data...');

var url = '/html5app/contact?operation=getallcontacts';

$.getJSON(url, function(data) {
saveOfflineContactData(data);
displayContactData(data);
});
}

清单 2 中的代码显示了如何将一个新的或者更新的联系人保存到服务器中。它使用了 jQuery ajax 函数。代码使用 HTTP POST 将数据发送到联系人 servlet。

清单 2. 把联系人保存到服务器中
function postEditedContact(dataString) {
postEditedContact(dataString, false);
}

function postEditedContact(dataString, suppressAlert) {
var cOntactId= $('input[name="contactId"]')[0].value;

$.ajax({
type: "POST",
url: "/html5app/contact",
data: dataString,
cache: false,
dataType: "json",
success: function(data) {
var result = data.result;

if (result)
{
if (contactId > 0)
{
if (!suppressAlert) {
alert("Contact was successfully updated.");
}
var lastModifyDate = data.lastModifyDate;
$('input[name="lastModifyDate"]')[0].value = lastModifyDate;
}
else
{
if (!suppressAlert) {
alert("Contact was successfully created.");
}

var lastModifyDate = data.lastModifyDate;
$('input[name="lastModifyDate"]')[0].value = lastModifyDate;
$('input[name="contactId"]')[0].value = data.contactId;
}

loadOnlineContacts();

hideEditForm();
}
else
{
alert('An error occurred saving contact ' + contactId + '.');
}
}
});
}

最后一个函数从在线数据库中删除记录。清单 3 显示了如何从服务器中删除记录。代码使用 jQuery getJSON 函数来调用联系人 servlet。

清单 3. 删除服务器上的联系人
function deleteOnlineContact(contactId, suppressAlert){
var url = '/html5app/contact?operation=delete&cOntactId=' + contactId;

$.getJSON(url, function(data) {
var result = data.result;
if (result) {
if (!suppressAlert) {
alert('Contact deleted');
}
loadOnlineContacts();
}
else {
alert('Contact ' + contactId + 'not deleted');
}
});
}

构建本地数据提供程序

本地数据提供程序在本地保存所有的选择列表和联系人数据。HTML5 规范包含用于持久存储的内容。使用哪一种技术取决于您的数据存储和浏览器支持。以下部分将讨论三种持久存储技术,以及使用所有 Web 浏览器支持的持久存储技术实现一个本地数据提供程序。

三种持久存储技术与 HTML5 有关:
localStorage:localStorage 使用平键-值存储来提供简单的数据存储。主要的 Web 浏览器,包括 Apple® Safari®、Google Chrome™、Microsoft® Windows® Internet Explorer®、Mozilla® Firefox® 和 Opera™ 均支持 localStorage。HTML5 localStorage 可实现同步,而且是如今惟一一个跨平台和跨浏览器支持数据库的存储机制。

WebSQL:WebSQL 最初的目的是为 Web 浏览器带来一个基于 Transact-SQL 的数据库。学习曲线很少以它同常见关系数据库的相似性为基础,这些关系数据库有 IBM® DB2®、Microsoft SQL Server®、Oracle® MySQL® Server 和 Oracle Database。在 Safari、Chrome 和 Opera 等浏览器中均支持 WebSQL。但是 Firefox 或 Internet Explorer 并不支持 WebSQL。WebSQL 可能会逐渐被淘汰掉,因为已经不再对 WebSQL 推荐的规范进行开发。

索引数据库 (Indexed DB):Indexed DB 是一种索引的层次性键-值存储,类似于许多商用云数据存储产品。放弃 WebSQL 对 Indexed DB 有利,而且现在 Firefox 和 Chrome 都支持 Indexed DB,将来发行的 Internet Explorer 10 也将提供相关支持。用于 Indexed DB 的应用程序编程接口 (API) 是异步的,支持索引、查询和事务。

本文中的示例解决方案利用 JSON 和 localStorage 来实现持久存储,主要是因为 localStorage 受到浏览器的广泛支持。

本地数据提供程序

localStorage 方法通过将联系人和字典数据序列化为一个 JSON 字符串,并将字符串保存在 localStorage 中,从而持久保存 approach 联系人和字典数据。当检索数据时,它就被并行化为一个 JSON 对象的数组并进行相应的处理。

在本地保存数据

清单 4 显示了如何将联系人数据保存到 localStorage 中。Javascript 函数 JSON.stringify 用于序列化 JSON 数据,服务器将这些数据返回到一个字符串,这样它才能存储在 localStorage 中。

清单 4. 将数据保存到 localStorage 中
// fetch data from server
...

// convert JSON data to a string
var cOntactDataString= JSON.stringify(data);

// persist contact data to localstorage
localStorage.setItem("contactData", contactDataString);

在本地检索数据

清单 5 显示了如何在 localStorage 中检索数据。第一步是从 localStorage 中获取 JSON 字符串。接着使用 Javascript 函数 eval 将字符串转换成 JSON 对象。使用自定义 Javascript 函数 displayContactData 来显示数据。

清单 5. 从 localStorage 中读取数据
function loadOfflineContacts() 
{
$('#contactList').empty();
$('#contactList').append('Loading contact data...');

var dataStr = localStorage.getItem("contactData");
var data = eval('(' + dataStr + ')');

displayContactData(data);
}

在本地删除记录

清单 6 显示了如何从 localStorage 中删除一个记录。

清单 6. 从 localStorage 中删除一个记录
function deleteOfflineContact(contactId) {
var dataStr = localStorage.getItem("contactData");
var data = eval('(' + dataStr + ')');

var recordUpdated = false;
$.each(data, function(i,item){
if (item.id == contactId) {
item.isDeleted=true;
recordUpdated = true;
return false;
}
});

if (recordUpdated) {
dataStr = JSON.stringify(data);
localStorage.setItem("contactData", dataStr);
alert("Contact was successfully deleted.");

loadOfflineContacts();
}
}

代码为:

  • 从本地存储中读取数据库并使其并行。
  • 彻底迭代记录直至找到 contactId 记录为止。
  • 将 isDeleted 标志设置为 true
  • 在数据同步函数中使用 isDeleted 标志。(参见 “数据同步” 部分。)
  • 将数据持久保存到 localStorage 中,并刷新数据网格。

在本地更新和创建记录

清单 7 显示了如何在 localStorage 更新或创建一个记录。

清单 7. 在 localStorage 更新记录
function updateLocalContact() {
var dataStr = localStorage.getItem("contactData");
var data = eval('(' + dataStr + ')');

var cOntactId= $('input[name="contactId"]')[0].value;

var recordUpdated = false;
if (contactId > 0) {
$.each(data, function(i,item){
if (item.id == contactId) {
item.isDirty=true;
item.firstName = $('input[name="firstName"]')[0].value;
item.lastName = $('input[name="lastName"]')[0].value;
item.street1 = $('input[name="street1"]')[0].value;
item.street2 = $('input[name="street2"]')[0].value;
item.city = $('input[name="city"]')[0].value;
item.state = $('select[name="state"]')[0].value;
item.zipCode = $('input[name="zipCode"]')[0].value;
recordUpdated = true;
return false;
}
});
}
else {
var newCOntactId= 0;
var nextId = 0;
while(newCOntactId== 0) {
var found = false;

nextId = nextId - 1;
$.each(data, function(i,item){
if (item.id == nextId) {
found = true;
return false;
}
});
if (!found) {
newCOntactId= nextId;
}
}
var lastModifyDate = "";
var newCOntact= {"street2": $('input[name="street2"]')[0].value,
"id":newContactId,
"street1":$('input[name="street1"]')[0].value,
"lastName":$('input[name="lastName"]')[0].value,
"isDirty":true,
"zipCode":$('input[name="zipCode"]')[0].value,
"state":$('select[name="state"]')[0].value,
"lastModifyDate": lastModifyDate,
"isDeleted":false,
"firstName":$('input[name="firstName"]')[0].value,
"city":$('input[name="city"]')[0].value};
var nextIndex = data.length;
data[nextIndex] = newContact;
recordUpdated=true;
}

if (recordUpdated) {
dataStr = JSON.stringify(data);
localStorage.setItem("contactData", dataStr);
alert("Contact was successfully updated.");
}

hideEditForm();
}

如 清单 7 所示,您可以:

  • 从 localStorage 中读取数据库并将其并行化。
  • 如果将要保存的记录的 contactId 不是 0(已更新),查找记录直至找到 contactId 记录。随后对其进行相应的更新。
  • 或者,如果记录是新的(contactId 不是 0),查找下一个为负值的 contactId
  • 将其分配到新纪录。
  • 将新纪录加到数据库。

数据随后被序列化为一个 JSON 字符串并保存到 localStorage 中。一个有效的 contactId(大于 0)将会在服务器同步化期间进行分配。为负值的 ID 是一个临时的 ID,用于将记录确定为新的。

了解 localStorage 很重要:

  • 限制为 5MB。(Indexed DB 应当在需要更多的数据存储时使用。)
  • 所有主要的 Web 浏览器支持。
  • 只使用字符串值工作。

下一步是构建使用 HTML5 的 UI。

构建使用 HTML5 的 UI

Contact Manager 示例应用程序有一个简单的 UI,并带有一个单一页面。它支持编辑和删除记录,并提供创建新纪录的功能。级联样式表 (CSS) 和动态 HTML(通过 jQuery)用于在必要时隐藏和显示创建/编辑子表单。

为了提供一致的用户体验,无论是在线还是离线状态都使用相同的页面;惟一的区别是数据提供程序是在执行操作时才调用。图 3 显示了该应用程序。

图 3. Contact Manager 应用程序
该图显示了 Contact Manager 应用程序

Javascript 模块

应用程序由四个自定义 Javascript 模块组成:

  • core.js 提供常见的 Javascript 函数并由另一个模块使用。
  • formEvents.js 提供表单和按钮事件处理。它根据在线或离线状态将数据库分派到正确的数据提供程序。
  • onlinedb.js 提供在线时与服务器通信的函数。
  • offlinedb.js 提供本地数据存储函数。

所有模块也使用最新版本的 jQuery 库遍历数据,从而形成异步的 Web 请求和动态 HTML。客户端使用 JSON 与服务器通信。

离线应用程序清单

HTML5 离线功能提供用于缓存的静态文件和资源。离线应用程序清单文件 (.appcache) 是为 Web 应用程序启动离线应用程序支持的关键文件。清单文件定义以下信息:

  • 哪些资源和页面在离线状态时可用。
  • 哪些资源只在线状态时可用。
  • 离线状态时显示资源的回退页面不可用。

清单文件包括三个部分:CACHENETWORK 和 FALLBACKCACHE 下的页面和资源在本地缓存。NETWORK 下的页面和资源从不缓存,且在线时惟一可用。离线状态下被请求的页面不可用时显示 FALLBACK 中指定的页面。NETWORK 部分中的星号 (*) 确保所有其他页面和 servlet 在线时惟一可用。如果丢失了 *,servlet 调用将失败(即使在线状态时也如此)。清单 8 显示了用于 Contact Manager 的清单文件。

清单 8. 离线应用程序清单
CACHE MANIFEST
# Revision 1
CACHE:
default.html
list.html
scripts/core.js
scripts/localdb.js
scripts/onlinedb.js
scripts/formEvents.js
http://code.jquery.com/jquery-1.7.2.min.js
NETWORK:
*
FALLBACK:
/ offline.html

当使用离线应用程序时,重要的是要知道:

离线应用程序清单文件扩展名 .appcache 需映射到 text/cache-manifest Multipurpose Internet Mail Extension (MIME) 类型。在 Apache Tomcat 中,通过将 mime-mapping 条目添加到服务器的 web.xml 文件(不是 Web 应用程序的 web.xml 文件)来完成此操作。如果 MIME 类型是错误的,大多数浏览器以静默方式忽略离线应用程序清单。
如果出现一个离线应用程序清单文件,则始终使用在本地缓存的资源(即使是在线状态)。
本地资源只在离线应用程序清单文件发生更改时更新,通常通过更改清单文件中评论的一个修订号来更新。对 HTML 或 CSS 资源所做的更改直到应用程序清单文件发生更改时才反映在 Web 浏览器中。
任何支持离线使用的页面必需具有以下内容:

  • 在线或离线
    有了 Javascript,您可以使用 navigator.onLine Boolean 来检测应用程序是在线状态还是离线状态。如果应用程序是在线状态,它将返回 True。

表单事件(在线/离线处理)

在 Contact Manager 中,无论是在线还是离线状态都使用相同的表单。使这个解决方案起作用的关键在于按钮和表单事件处理程序。查看navigator.onLine 来确定需要调用(本地或在线)哪项操作。清单 9 显示了用于加载联系人数据的示例。

清单 9. 加载数据(在 HTML BODY 的 onLoad 事件中)
if (navigator.onLine) 
{
// selection list needs to be populated prior to synchronizing data
// the list is updated from the online dictionary later
populateOfflineStates();

setStatusText("Synchronizing contact data with server...");
synchronizeContacts();

setStatusText("Loading dictionary data from server...");
populateOnlineStates();

setStatusText("Loading contact data from server...");
loadOnlineContacts();
}
else
{
alert('You are currently offline.');
populateOfflineStates();
setStatusText("Loading contact data from local storage...");
loadOfflineContacts();
}

数据同步

当处于在线状态时,所有的 CRUD 操作都使用 servlet 来创建、修改和删除。本地缓存也在在线数据库发生更改时更新。

当处于离线状态时,所有的 CRUD 操作使用本地数据提供程序来更改。在重新连接服务器时:

  • 在服务器上持久保存本地创建的所有记录。
  • 在服务器上更新本地修改的所有记录。
  • 在服务器上删除本地删除的所有记录。

清单 10 显示了完整的同步化方法。在同步化期间,相同的在线函数用于创建、更新和删除操作。第一步是使用 jQuery $.each 函数迭代本地记录。

在本地更新或创建的记录均使用 isDirty 属性进行标记。如果 Save 操作其惟一的记录 ID 是负值(不是由 MySQL 数据库分配的),则将其确定为新的。在本地删除的记录使用 isDeleted 属性进行标记。

清单 10. 使离线更改与服务器同步
var recordsUpdated = 0;
var recordsCreated = 0;
var recordsDeleted = 0;

$.each(data, function(i,item){
if (item.isDeleted) {
deleteOnlineContact(item.id, true);
recordsDeleted++;
}
else if (item.isDirty && !item.isDeleted) {
$('input[name="contactId"]')[0].value = item.id;
$('input[name="firstName"]')[0].value = item.firstName;
$('input[name="lastName"]')[0].value = item.lastName;
$('input[name="street1"]')[0].value = item.street1;
$('input[name="street2"]')[0].value = item.street2;
$('input[name="city"]')[0].value = item.city;
$('select[name="state"]')[0].value = item.state;
$('input[name="zipCode"]')[0].value = item.zipCode;

var dataString = $("#editContactForm").serialize();
postEditedContact(dataString, true);
if (item.id > 0) {
recordsUpdated++;
}
else {
recordsCreated++;
}
}
});

var msg = "Synchronization Summary\n\tRecords Updated: " + recordsUpdated +
"\n\tRecords Created: " + recordsCreated +"\n\tRecords Deleted: " + recordsDeleted;
alert(msg);

最新的数据从使用 getcontacts 操作的数据库中取得,并将其显示。其他用户所做的任何更改将会被反映出来。随后在本地保存数据以确保其在离线状态时可用。

结束语

在本文中,示例显示了一个很好的在线和离线支持的模式。一致的用户体验维护的方式是:使用在线和离线模式的单一 HTML 页面并根据在线/离线状态以事件处理的形式调用相应的在线/离线数据提供程序。

数据同步算法提供了一个很好的基础;它使得记录的离线创建、删除和修改实现同步化。然而,它不是一种生产就绪代码。例如,它并不处理由另一个用户在本地和服务器上修改同一个记录发生的冲突。



推荐阅读
  • 本文介绍了Java后台Jsonp处理方法及其应用场景。首先解释了Jsonp是一个非官方的协议,它允许在服务器端通过Script tags返回至客户端,并通过javascript callback的形式实现跨域访问。然后介绍了JSON系统开发方法,它是一种面向数据结构的分析和设计方法,以活动为中心,将一连串的活动顺序组合成一个完整的工作进程。接着给出了一个客户端示例代码,使用了jQuery的ajax方法请求一个Jsonp数据。 ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • 这是原文链接:sendingformdata许多情况下,我们使用表单发送数据到服务器。服务器处理数据并返回响应给用户。这看起来很简单,但是 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 本文介绍了Web学习历程记录中关于Tomcat的基本概念和配置。首先解释了Web静态Web资源和动态Web资源的概念,以及C/S架构和B/S架构的区别。然后介绍了常见的Web服务器,包括Weblogic、WebSphere和Tomcat。接着详细讲解了Tomcat的虚拟主机、web应用和虚拟路径映射的概念和配置过程。最后简要介绍了http协议的作用。本文内容详实,适合初学者了解Tomcat的基础知识。 ... [详细]
  • Ihavethefollowingonhtml我在html上有以下内容<html><head><scriptsrc..3003_Tes ... [详细]
  • 本文介绍了前端人员必须知道的三个问题,即前端都做哪些事、前端都需要哪些技术,以及前端的发展阶段。初级阶段包括HTML、CSS、JavaScript和jQuery的基础知识。进阶阶段涵盖了面向对象编程、响应式设计、Ajax、HTML5等新兴技术。高级阶段包括架构基础、模块化开发、预编译和前沿规范等内容。此外,还介绍了一些后端服务,如Node.js。 ... [详细]
  • Android实战——jsoup实现网络爬虫,糗事百科项目的起步
    本文介绍了Android实战中使用jsoup实现网络爬虫的方法,以糗事百科项目为例。对于初学者来说,数据源的缺乏是做项目的最大烦恼之一。本文讲述了如何使用网络爬虫获取数据,并以糗事百科作为练手项目。同时,提到了使用jsoup需要结合前端基础知识,以及如果学过JS的话可以更轻松地使用该框架。 ... [详细]
  • Node.js学习笔记(一)package.json及cnpm
    本文介绍了Node.js中包的概念,以及如何使用包来统一管理具有相互依赖关系的模块。同时还介绍了NPM(Node Package Manager)的基本介绍和使用方法,以及如何通过NPM下载第三方模块。 ... [详细]
  • CentOS 7部署KVM虚拟化环境之一架构介绍
    本文介绍了CentOS 7部署KVM虚拟化环境的架构,详细解释了虚拟化技术的概念和原理,包括全虚拟化和半虚拟化。同时介绍了虚拟机的概念和虚拟化软件的作用。 ... [详细]
  • SpringMVC接收请求参数的方式总结
    本文总结了在SpringMVC开发中处理控制器参数的各种方式,包括处理使用@RequestParam注解的参数、MultipartFile类型参数和Simple类型参数的RequestParamMethodArgumentResolver,处理@RequestBody注解的参数的RequestResponseBodyMethodProcessor,以及PathVariableMapMethodArgumentResol等子类。 ... [详细]
  • 在Android中解析Gson解析json数据是很方便快捷的,可以直接将json数据解析成java对象或者集合。使用Gson解析json成对象时,默认将json里对应字段的值解析到java对象里对应字段的属性里面。然而,当我们自己定义的java对象里的属性名与json里的字段名不一样时,我们可以使用@SerializedName注解来将对象里的属性跟json里字段对应值匹配起来。本文介绍了使用@SerializedName注解解析json数据的方法,并给出了具体的使用示例。 ... [详细]
  • 本文介绍了如何使用JSONObiect和Gson相关方法实现json数据与kotlin对象的相互转换。首先解释了JSON的概念和数据格式,然后详细介绍了相关API,包括JSONObject和Gson的使用方法。接着讲解了如何将json格式的字符串转换为kotlin对象或List,以及如何将kotlin对象转换为json字符串。最后提到了使用Map封装json对象的特殊情况。文章还对JSON和XML进行了比较,指出了JSON的优势和缺点。 ... [详细]
  • 本文介绍了一个React Native新手在尝试将数据发布到服务器时遇到的问题,以及他的React Native代码和服务器端代码。他使用fetch方法将数据发送到服务器,但无法在服务器端读取/获取发布的数据。 ... [详细]
  • 本文介绍了在满足特定条件时如何在输入字段中使用默认值的方法和相应的代码。当输入字段填充100或更多的金额时,使用50作为默认值;当输入字段填充有-20或更多(负数)时,使用-10作为默认值。文章还提供了相关的JavaScript和Jquery代码,用于动态地根据条件使用默认值。 ... [详细]
author-avatar
Mua--于毛毛在路上
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有