欢迎各位兄弟 发布技术文章
这里的技术是共享的
00-00) 在这个课程里,我们会去开发一个小应用,应用会使用 Drupal 做为后台来提供数据。我们可以先去把 Drupal 配置成可以响应, 应用客户端软件请求的 Web 服务器。
这样,在应用里,可以向 Drupal 的 Web 服务发送请求 ... 比如发送用户登录的请求 .. Drupal 的 Web 服务会分析发送过来的请求,如果验证通过的话,会给应用返回对应的数据。
你也可以在应用里发送用户登出的请求,可以使用 Views 创建一个内容的列表 ... 然后在应用里去请求查看这个内容列表 ...
点击列表里的内容,可以发送请求查看指定的节点内容,在应用里,你可以创建一个页面来显示出节点里的内容。
点击界面上的编辑按钮,可以向 Drupal 服务发送要编辑内容的请求 .... 或者,点击删除按钮... 去发送删除内容的请求。
我们也可以给应用添加一个能够创建内容的页面 ... 输入相应的内容 ... 然后点击 提交 ... 会向 Drupal 服务发送创建新内容的请求 ...
验证通过以后, Drupal 会在数据库里存储我们创建的内容。
哦,最后,我们会使用 PhoneGap ,把这个小应用包装成功以直接安装在移动设备上的本地应用程序。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00-01)
Web Services 就是 Web 服务,是一种通过 Web 让客户端和服务器进行对话的通信方式。比如我们要制作一个客户端的应用程序,在这个应用程序里可以向服务器去发送一个请求。服务器接收到这个请求一下,先会分析一下,看看这个客户端应用想要的东西,处理一下,然后返回所请求的数据。
这样,我们在客户端的应用里,会接到收服务器返回来的数据,你可以决定怎么样去使用这些数据。在这个课程里,这个可以响应客户请求的 Web Service ,可以使用 Drupal 来提供。
这需要给 Drupal 去安装一个 Services 模块,在未来版本的 Drupal 版本里,Web Service 会集成到 Drupal 的核心里面。
安装了 Services 模块以后,可以去添加一个服务,这个服务可以使用 REST 标准,这种使用 REST 标准的 Web Service ,也叫它 RESTful Service ...
你可以把它想像成一种处理客户请求的方法。 这种 RESTful 服务需要通过地址的形式来发送请求 ...
我们可以配置 Drupal 的 RESTful 服务,决定服务可以响应什么样的请求 ... 比如,可以请求文章内容,创建,编辑,或者删除文章内容,可以请求用户登录,退出登录,上传文件等等。
这些叫做服务的 Resources ,也就是服务的资源 ,也可以想像成服务的功能。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00-02)
这个课程里我们会用到 Drupal 做为应用的数据后台,还有 Web Serivce 服务器。你可以先去安装一个最新版的 Drupal ,这个课程里,我会用 Drupal 7 的最新版本来演示。
你需要给 Drupal 安装一些必须的模块。 首先,最重要的是 services 模块,这个模块可以允许我们去配置 Web Services 服务器。在我们要做的这个小应用里,可以向这个 Drupal 服务器发送请求,服务器会分析这个请求,并且会把相应的数据返回给我们的应用。
另外,我们还需要安装 views 模块,还有 views_datasource 模块 ... views 模块可以创建内容的列表 ... views_datasource 模块其实是一个 views 的显示格式 .. 比如它可以把 views 生成的内容列表输出成 json 格式的 ...
在应用里面,可以请求这个 json 格式的 views 生成的内容列表 ... 这样在我们的应用里,可以使用这个内容列表里的数据,你可以选择返回来的数据,放在你想要的地方显示出来。
另外,安装这些模块,你可能需要先安装他们所依赖的一些模块 ... 在 Drupal 后台,模块这个界面上,会给你显示出,模块所依赖的模块,下载这些依赖的模块,放在你的模块目录里面。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
00-03)
在这个视频里我们去准备一下应用需要用到的一些资源 ... 先打开 Web 服务器的发布目录 ... 这里 Drupal 这个目录里面就是我们需要用到的 Drupal 网站。
在这个课程的资源包里 00-03 这个目录里面,你可以找到这个应用的框架 ... 把里面的东西复制到这个网站发布目录里。
然后用编辑器打开这个 app 目录 ... 这里我用的是 Brackets 编辑器...
下面,我们看一下这里目录里的东西 ...
index.html 就是应用的界面 .. . 基本上现在它是一个空白的页面 ...
在页面的头部 .. 配置了基本的 viewport 设置 .. 链接了 jQueryMobile 的样式表 ... 这个应用的界面,我们需要用到 jQueryMobile ...
然后是 jQuery ... 接着是 jQueryMobile ... 它是在 jqm 这个目录里面。
在页面的底部 ... 嵌入了 index.js 这个脚本文件 ... 在这个文件里,我们会去编写应用需要的一些代码 ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
01-01)
在这个视频我们使用 Drupal 去创建一个 Web Services 服务器,先打开 模块 ... 在这里,先启用一下 services 模块,还有 Servivces 的 REST Server ... 在这个地址里,你可以下载到这个模块 .. 保存 ...
然后打开 结构 菜单 ,找到服务... 在这个界面上,我们可以管理网站上的服务,也就是 web services ...
点击 添加,去添加一个新的服务 ..
先输入服务端点的机读名称,也就是在程序内部分使用的服务的名字 ... 这个名字可以使用小写的字母,数字,还有下划线。
输入 myservice .. 服务器,选择 REST ... 端点的路径,也就是访问这个服务的地址 ... 这里我们同样使用 myservice ...
勾选一下 启用调试模式 ... 还有 身份验证 下面的 会话认证 ...
完成以后,点击 保存 ...
测试
下面,我们可以去验证一下这个服务端点 ... 在地址栏里输入网站的地址 ... 后面加上 服务端点 的路径 .. 就是 myservice ... 然后回车 ..
在页面上,会显示 服务的端点 "myservice" 已成功设置。 这就说明我们成功的配置了一个服务端点 ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
01-02)
服务的资源,就是服务能做的事情,比如,你可以让用户能通过服务去登录,登出,可以查看节点内容,创建新的节点,或者可以编辑和删除节点内容等等 ...
打开 结构,服务 ... 找到之前我们添加的服务,然后点击 编辑源 ... 在这个界面上,可以指定服务能做的事情 ...
它给我们分成了几个不同的区域, comment ,也就是评论相关的东西,file 是文件, node 就是节点内容,system 是系统,另外还有分类,和用户。
我们先打开 node 这个区域 ... 在这里先勾选一下 retrieve .... 它可以让我们通过服务去查看节点内容 ...
先保存一下 ...
测试
打开一个新的浏览器标签 ... 输入http://127.0.0.1/app/myservice/node/1
myservice 是服务的端点 ... 后面的 node 表示节点 .. 数字 1 是 id 为 1 的节点内容 ...
现在你看到的东西就是 myservice 这个服务根据我们的请求,响应,并且返回来的内容 ... 返回的这个内容的格式是一个 xml 文档 ... 文档的内容就是节点 1 相关的 ...
节点的标题 ... 类型 ... 语言,内容 ... 作者等等 ...
我们可以在移动应用上,解析这个返回来的 xml 文档,然后去设计一个界面,把想要的内容放在指定的地方显示出来 ...
之所以返回了节点的内容,是因为我们勾选了服务资源里面 node 区域里的 retrieve ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
01-03)
向 myservice 这个服务,按照这个形式来发送请求,在默认的情况下, 给我们返回一个 xml 文档形式的结果 ... 在这个地址的后台加上一个 .json ... 然后回车 ...
返回的结果会是 json 形式的数据 ... 下面,我们可以打开 REST Console .... 这是一个用在 Chrome 浏览器上的一个小插件,你可以在 Chrome 商店里,免费的下载到这个 REST Console 。
在 Target 区域里面, Request URI 可以输入请求的地址 ... 在这里还是输入刚才的请求的地址 ...http://127.0.0.1/app/myservice/node/1
设置一下 Request Method ,请求的方法 ... 比如 GET ... POST ... PUT ... 等等 . .. 这里设置一下普通的 GET 请求,因为我们只想去获取到一些东西 ...
点击 Send ... 发送按钮 ...
在 Response ,响应这个区域 ... Response Body 是响应返回来的结果 ... 这里得到的结果跟我们刚才看到的直接在浏览器里输入这个请求的地址是一样的 ... 返回的结果是 XML 格式 ...
控制响应的格式
下面,我们可以设置一下请求的 header ,也就是请求的头部信息 ...
在这里勾选一下 Content-Type ... 设置一下 内容类型 这个头部信息 ... 输入 application/json 。它的意思就是现在这个 GET 请求想要得到的响应的结果的格式是 json 格式的 ...
点击 send ... 如果请求成功的话,myservice 这个服务会给我们返回 json 格式的数据。 这个得到的数据就是请求的节点内容 ... 在我们的应用里面,可以先解析一下这个 json 数据,然后可以在指定的地方显示它。
设置服务的响应格式
在请求的时候,我们设置了请求的头部,要求服务返回的数据的格式,这其实是需要单独设置一下 ... 回到 Drupal 网站,打开 结构,服务 ..
编辑一下 myservice 这个服务 ... 打开 服务器 这个选项卡 ... 在这里,你可以设置服务可以解析的数据类型,还有响应的格式,在这里,默认已经勾选了 json 这个格式,所以,我们还能在请求的时候,通过设置 header 让服务返回 json 数据 ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
01-04)
前面的视频里我们直接使用浏览器或者浏览器的插件向服务发送 HTTP 请求。在真正的应用里,需要使用脚本去发送请求,也就是使用 JavaScript 的代码来发送 HTTP 请求。
可以使用 AJAX,我们先要创建一个 XMLHttpRequest 这个对象的实例,然后用这个新创建的对象的 open() 方法去发送 HTTP 请求,设置一下请求的方法,地址,验证一下请求的状态,成功以后,我们就可以去使用响应回来的数据了。
另外,用 send() 方法,可以向服务器发送数据。
jQuery 里面提供了比较容易的方法去使用 AJAX,下面,我们可以一起来看一下使用 jQuery 的 ajax 方法来发送 HTTP 请求 ..
代码
打开应用的 index.js 这个文件 .. 输入 $.ajax(); ... 意思就是去调用 jQuery 的 ajax 这个方法 ... 下面要去配置一个这个方法里面的一些设置,这个设置是一个对象,所以,先输入一组花括号 ...
$.ajax({});
首先,可以指定一下想要请求的地址 ... 这个地址属性是 url ... 后面加上具体的地址 ..
url:http://127.0.0.1/drupal/myservice/node/1,
不同的属性之间用逗号分隔一下 ... 再设置请求的类型,也就是请求的方法... 这个属性是 type .... 把它设置成 GET ...
type: 'GET',
现在,这段代码的意思就是,使用 HTTP 的 GET 方法,去请求http://127.0.0.1/drupal/myservice/node/1 这个地址 ... 如果请求成功的话,会去执行一个函数 ... 这个函数就是 success 属性里面定义的 ....
success: function (data) {},
这里我们用一个匿名函数 ... 请求成功以后,会返回一个响应回来的数据的对象,这个对象可以作为这个函数的一个参数 .... 这样在这个函数里面,我们可以去处理这个返回来的对象。
先用一个简单的 console.log ... 把这个对象输出到控制台上 ..
console.log(data);
测试
保存一下,回到浏览器 ... 然后打开应用的首页 ... 在控制台上,你会看到返回来的结果... 是一个 xml 文档 ...
在请求的时候,可以设置一下 ajax 方法里的 dataType 数据,去指定一下想要得到的返回来的数据的类型 ... 回到 index.js ... 输入一个 dataType ... 把这个属性的值设置成 json ...
dataType: 'json',
保存 ... 再回到浏览器 ... 刷新 ...
你会发现,现在给我们返回来的结果是一个对象 ... jQuery 的 ajax 方法自动把返回来的 json 数据转换成 JavaScript 的对象 ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
01-05)
这个视频我们去设置一下,当请求发生错误的时候要做的事 ... jQuery 的 ajax 方法里,可以在 error 属性里指定一个函数,这个函数会在请求失败的时候去调用 ...
先打开 index.js ,找到前面视频里的这段代码 ... 另起一行 ... 设置一下 error 属性 ... 这个属性的值是一个函数 ... 这里我们可以用一个匿名函数 ... 或者可以单独去定义一个函数 ..
输入 onError ...
在上面,再去定义一下这个 onError 函数 ... 这个函数可以接受三个参数 ... jqXHR ... 它是 jQuery 的 XMLHttpRequest 对象 ... 还有 textStatus ... 这个参数是错误的类型。它可能的值比如 ... timeout 请求超时了 ... error 发生了错误 ... abort 放弃了请求 ..
第三个参数是 errorThrown ... 这个参数是具体的发生的错误...
/**
* 处理请求发生的错误
*/
function onError(jqXHR, textStatus, errorThrown) {
//console.log(jqXHR);
//console.log(textStatus);
//console.log(errorThrown);
}
把这三个参数接收到的东西输出到控制台上 .. 下面,我们去请求一个网站里面不存在的东西 ... 比如 node/10000 ...
测试
保存 .... 回到浏览器 ... 刷新一下 ... 在控制台上,会输出一些东西 ... 第一个错误是因为我们想把请求成功以后的数据输出到控制台上 ... 提示 GET 这个地址,返回的代码是 404 ,表示没有找到这个地址 ...
第二个输出的东西是 jqXHR 对象 ... 后面是错误的类型 ... 最后是具体发生的错误 ... 这个地址显示了一个乱码 ... 这应该是 chrome 的开发者工具的一个 bug ...
可能是中文编码的问题 ... 这个乱码其实就是中文 未找到节点 ...
在 jqXHR 里面,我们可以同样可以找到这个错误 ... 打开这个对象 ...
因为请求的时候,设置要返回的数据类型是 json ,所以这里会有个 responseJSON 属性,打开这个属性,里面会有提示 ,未找到节点 10000 ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
02-01)
服务的 system ,系统资源里面的 connect 这个资源,可以让我们获取到当前登录的用户的一些相关的信息,用户名,上次登录的时间,区域的设置等等 ...
注意这个当前的登录用户并不是所有的登录到网站上的用户,而是用户自己,因为我现在使用的是王皓这个用户的身份登录到了网站上,所以发送请求返回来的信息应该就是王皓这个用户。
先打开 结构,服务,编辑一下这个 myservice .. 在 资源 这里,找到 system 区域,先勾选一下 connect 这个资源 ... 这个 connect 就相当于是用服务获取当前登录用户的功能。
我们可以先用它来获取到匿名用户的相关信息 ... 可以先退出当前的登录 ... 或者,可以打开 编辑 选项卡 ... 去掉 身份验证 下面的 会话认证 ... 这样服务不会验证发送请求的用户的身份,也就是说所有的请求都会通过匿名用户的身份完成的 ...
代码
打开应用的项目的 index.js 这个文件 ... 下面,我们可以通过代码去发送这个请求 ...
可以基于前面视频里的代码去修改一下 ... 用的是 jQuery 的 ajax 方法 ... 修改一下请求的地址 ...http://127.0.0.1/drupal/myservice/system/connect
请求的类型,换成 POST ... 要求响应的类型还是 json .. 失败的时候去执行 onError 这个函数 ... 成功的话,会把返回来的数据输出到控制台上 ..
测试
保存 ... 回到浏览器 ... 刷新 ... 在控制台上,你会看到返回来的东西 ... session id ... session name ...
打开 user 这个对象 ... roles ... 角色 ... 在这里,你会发现,是 anonymous user ... 也就是匿名用户 ... 因为之前我们取消勾选了服务的 会话验证 这个选项 ... 所以,所有的请求都会使用匿名用户的身份。
回到 Drupal ,找到 myservice 服务 ... 再勾选一下这个 会话验证 选项 ... 保存
再回到浏览器 ... 刷新 ... 这次会给我们返回一个 401 验证未通过的错误... 应该是 CSRF验证失败了 .. 这是因为,这个请求需要验证用户的身份,像这样需要验证用户身份证的请求,为了防止身份的欺诈都需要先去请求一个 CSRF Token ...
在下面的视频里,我们再去看一下怎么样请求这个 CSRF Token ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
02-02)
为了安全,我们向服务发送的需要验证用户身份的请求,都需要先去向服务请求一个 CSRF Token ... 它其实就是一串随机的字符串,然后使用这个 token 去发送想要的请求。比如获取当前登录的用户的信息,用户登录等等...
想要去请求 CSRF Token ,我们得先去勾选一下服务资源 ... 打开 结构,服务,编辑一下 myservice ... 打开 user 区域 ... 勾选一下 token ... 它的功能就是可以返回 CSRF Token 。
保存 ... 回到之前编辑的代码 ...
代码
这里我们可以再用一个 ajax 方法去发送一个请求,请求的地址就是刚才启用的 user/token ... 类型是 POST ... 要求返回的数据的类型是 json ... 发生错误去执行 onError ... 请求成功的话,在控制台上输出返回来的结果... 保存一下 ...
$.ajax({
url: 'http://127.0.0.1/drupal/myservice/user/token',
type: 'POST',
dataType: 'json',
error: onError,
success: function (CSRFToken) {
console.log(CSRFToken);
}
});
预览
回到浏览器 ... 刷新 ... 这里会显示一个对象 ... 这个对象有一个 token 属性,这个属性的值就是请求的 CSRF Token ... 我们要做的就是使用这个 token 去发送其它的请求,比如要求返回当前登录用户的请求。
代码
再回到 index.js ... 把在上一个视频里设置的 ajax 请求,放在这个token 请求的里面。 在这个获取当前登录用户的请求里面,我们得去设置一下请求的一个 header ,也就是头部信息。
可以给这个请求添加一个 beforeSend 属性 ... 属性的值是一个匿名函数 ... 把请求的这个对象交给这个函数 ...
再用这个对象的 setRequestHeader 方法去设置一下请求的头部 .. 这里我们需要去设置一下 X-CSRF-Token 这个头部信息 ... 它的值,就是请求 user/token 返回来的那个 token ...
这个 token 的具体的值是在返回来的对象的 token 属性里面 ... 返回来的对象命名成了 CSRFToken ... 用一个 CSRFToken.token 可以访问到这个 token 属性的值 ...
/**
* 获取到当前登录的用户信息
*/
$.ajax({
url: 'http://127.0.0.1/drupal/myservice/user/token',
type: 'POST',
dataType: 'json',
error: onError,
success: function (CSRFToken) {
$.ajax({
url: 'http://127.0.0.1/drupal/myservice/system/connect',
type: 'POST',
dataType: 'json',
error: onError,
beforeSend: function (request) {
request.setRequestHeader('X-CSRF-Token', CSRFToken.token);
},
success: function (data) {
console.log(data);
}
});
}
});
其实这里我们做的就是先去请求一个 token ,然后把这个 token 作为请求当前登录用户的一个头部信息发送给服务。这样才能验证成功。保存一下 ...
回到浏览器再去看一下 ...
在控制台上,你会发现,不会再显示那个 CSRFToken 验证失败这个错误了 ... 给我们返回来的是一个当前登录的用户的对象 ...
在这个对象里,包含当前登录的用户的相关的信息。
里面有用户的名字,邮件地址,用户的角色,创建的日期,上次登录的时间等等 ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
02-03)
发送请求,会返回相应的数据,通常我们希望服务返回来的数据都是 json 格式的,使用 jQuery 的 ajax 方法发送的请求,会自动把返回来的 json 格式的数据转换成 JavaScript 的对象的形式 ... 这样我们就可以直接去使用这些数据,把想要的东西显示到应用的界面上。
这个视频我们一起来看一下,把服务返回来的当前登录的用户的一些信息显示在一个应用的页面上。
index.html(#折叠好)
先去看一下这个页面需要的 html 结构... 这里我们用的是 jQuery Mobile 的页面的结构,先是一个大的 div 容器 ... 上面有一个 data-role 属性,属性的值是 page ,表示这是一个页面,在这个页面上,我自己定义了一个 id ,是 user-profile ,这个 id 就是这个页面的名字。
在它的里面分成了三个部分,页头,主体内容,还有页脚。他们上面都有对应的 data-role 属性,页头是 header,主体内容是 main ,页脚是 footer
这里我们先看一下主体内容,因为一会儿,要把返回来的用户信息输出到这个容器里面,我在这个容器上事先定义了一个 id ,user-profile-body ..
等会儿,可以用到这个 id 来定位这个容器,再把想要的内容输出到这里。(#打开 main)现在, 它只是一组空白的 div 标签。
index.js
下面,我们再去处理一下要用到的代码。打开 index.js ...
还是基于前面的视频里的代码 ... 在请求查看当前登录用户信息成功以后,在这个 success 属性后面的函数里,可以去输入一些代码。返回来的用户信息会在这个 data 对象里。下面,我们再到浏览器的控制台上,去看一下这个对象里面的东西。
回到浏览器 ... 刷新 ... 打开这个对象 ... 在它的 user 属性里,这个 user 属性的值也是一个对象 ... 在这里可以找到我们想要用到的东西,比如用户名,是在 user 这个对象的 name 这个属性里面 ...
另外,可以再用一个 created 属性... 这的值是用户注册的时间 ... 这个时间是从 1970年1月1号,到用户注册的那个时间的秒数 ... 在代码里,可以处理一下它,把它转换成一般人都能看得懂的日期。
回到 index.js ,先定位一下想要显示这些内容的那个容器 .. 然后使用 jQuery 的 html 方法,去设置一下这个容器里面的东西。先去定义两个变量 ...
var userName = data.user.name,
userCreated = new Date(data.user.created * 1000);
userName 里面的值就是用户的名字,用户的名字就是返回来的对象的 user 这个属性里面的 name 这个属性的值 ... userCreated 里的值是用户注册的日期,因为 JavaScript 里的时间是从 1970年1月1号 到某个时间的毫秒数 ... user 对象里的 created 属性里的值是秒数,所以,需要让它乘以 1000 ,转换成毫秒 ...
success: function (data) {
console.log(data);
var userCreated = new Date(data.user.created * 1000);
$('#user-profile-body').html(
'<h3>' + userName + '</h3>' + '<p><strong>注册时间:</strong>' +
userCreated.toLocaleDateString() + '</p>'
);
}
下面我们要做的就是,把用户名,用一组 h3 标签包装一下,用一组 p 标签包装一下用户注册的日期,这里使用一个 toLocaleDateString ,可以转换一下日期的显示格式 ... 然后再把它们一起放在 user-profile-body 这个 id 的容器里面。
预览
保存,回到浏览器 ... 刷新一下 ...
现在, 在这个页面上,会显示出,当前登录的用户的名称 ... 还有他的注册的日期。
看完 02-03
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
02-04)
想通过服务让用户退出当前的登录,先要去启用一个服务资源,打开 结构 - 服务,编辑一下 myservice ... 在 用户 这个区域里面,勾选一下 logout ... 保存一下 ... 再回到 index.js
先设置一个 jQuery 的 ajax 请求,我们可以基于之前的代码去修改一下 .. 复制一下 ... 粘贴到下面 ...
在获得 token 成功以后,去发送 退出登录 的请求 ... 请求的地址是http://127.0.0.1/drupal/myservice/user/logout
类型是 POST,数据的类型仍然是 json , 再去设置一下请求成功以后,要做的事 ,可以在控制台上输出返回来的数据 ...
测试
保存一下,回到浏览器 ... 刷新一下页面 ... 这样会去执行刚才我们设置的代码,会发送退出登录的请求 ...
在控制台上,会输出一个 true ... 证明我当前已经成功的退出了登录 ... 再刷新一下 ... 现在,应用的界面上已经不能再显示出当前登录的用户信息了,因为刚才已经退出了登录 ...
下面再打开 Drupal 的网站去看一下 ... 你会发现,同样,已经退出了登录。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
02-05)
通过服务让用户进入登录的状态,先要启用服务的 login 资源,然后去设计一个登录的页面,这个页面上的主要内容就是一个登录的表单,用户可以输入用户名和密码,点击登录按钮。触发一个登录的请求。
先打开 结构 - 服务,编辑一个 myservice ,在 user 区域里面,勾选一下 login ,这样我们才能通过 myservice 这个服务让用户进行登录。
然后再退出登录一下 .. 一会儿我们直接在应用里去登录 ...
index.html
下面先去看一下我提前准备的一个登录页面。打开 index.html .... 这里我又添加了一个新的页面,在 jQueryMobile 里面,一个页面其实就是 data-role 属性为 page 的 div 标签。
在这个页面上,我添加了一个 id,是 user-login ... 再看一下这个页面的主体部分 ...
主体部分的内容是一个表单,两个文本框,用户名和密码,还有一个 登录 按钮 ... 我们可以使用代码获得到用户在 用户名 和 密码 文本框里输入的内容,然后当用户点击 提交 按钮的时候,把这个获取到的数据发送给 Drupal 的服务,它会验证用户的身份再决定是否可以让用户登录。
index.js
下面,我们再去设置一下需要的代码 ... 回到 index.js ... 先注释掉之前设置的 用户登出 的这段代码 ... 不然每次刷新页面都会执行这个登出的请求 ... 在后面的视频里,再去解决这个问题 。
这个请求需要一个事件去触发它,这个事件就是用户点击了 提交 按钮。 我们可以把这个请求放在一个函数里面,然后再去设置,当用户点击了 提交按钮以后,去执行这个函数,这样也就会去请求登录 。
这个函数可以叫它 userLogin .. 登录的请求,可以基于之前设置的这段代码去修改一下 .. 复制 ... 粘贴 ...
请求 token 成功以后,去发送 login 登录的请求。请求的地址是http://127.0.0.1/drupal/myservice/user/login ... 类型还是 POST,数据的类型是 json ...
在这个请求里,我们得发送一些数据,也就是用户输入的用户名和密码。
在这个函数里,先去获得用户输入的这些数据,把用户在用户名里输入的东西,命名为 userName ,把在密码框里输入的东西,命名成 userPassword ... 这里我们使用的是 jQuery 的方法 ... 定位这两个文本框元素 ... 再调用 val 方法去获得里面的值 。
var userName = $('#user-login-name').val(),
userPassword = $('#user-login-password').val();
然后再去设置一下登录请求,在这个请求里添加一个 data 属性 ... 属性的值就是发送给服务的数据,这个数据需要使用特定的形式。
先是 username ,加上一个 等号,等号的右边是用户的用户名,前面,我们已经把用户输入的用户名交给了 userName 这个变量 ...
然后加上一个 & 符号,再输入 password .. 等号,等号右边是用户输入的密码 ...
(# 开启 请求数据 ...)
登录成功以后,把请求返回来的数据,输出到控制台上 .. console.log(data);
下面,我们需要去处理一下用户点击 提交 按钮要做的事 ... 点击 提交 按钮以后,去执行 userLogin ... 保存一下文件 ...
// 点击 登录 按钮时执行 userLogin()
$('#user-login-submit').click(userLogin);
配置服务
这个请求会发送数据给服务,这个数据我们用了一个特定的格式,想让服务能识别这种格式,需要再去配置一下服务 ... 打开 Drupal 的网站 ... 先登录一下 ... 打开 结构 ... 服务 ... 编辑 myservice ... 点击 服务器 这个选项卡 ...
在 请求解析 这个区域里面,勾选一下 application/x-www-form-urlencoded
点击 保存 ... 然后再 退出登录 ...
测试
下面我们可以先打开 用户登录 的页面 ... 在地址栏里输入这个页面的地址 ... 一个 # 号,后面加上在用户登录页面上定义的 id ..
输入 用户名 ... 再输入 密码 ... 点击 登录 ...
在控制台上,你会看到登录成功以后返回来的数据 .. 这个数据就是当前登录的这个用户相关的东西。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
02-06)
这个视频我们可以去完善一下用户相关的页面和功能。我们可以让用户在点击右上角这个 用户 图标 ,打开用户资源的页面 ...
如果用户还没有登录的话,会把用户重定向到 用户登录 页面。 用户在登录以后,会返回到用户档案这个页面上。
index.html
先去看一下页面的 html ,打开 index.html ... 这里我又添加了一个空白的首页 ... 现在这个应用一共有三个页面,一个空白的首页,一个用户档案页面,还有一个用户登录的页面。
每个页面上的页头部分都有一个工具条。工具条上有一个返回首页的按钮,还有一个可以打开用户档案页面的按钮。
index.js
再打开 index.js ... 首先要做的,可以把获取当前登录用户信息这个请求放在一个函数里,然后再设置一下,当用户打开 用户档案 页面以后,去发送这个请求。
这个函数可以叫做 getCurrentUser() ...
下面再去设置如果当前活动的页面是 用户档案 页面的话,去执行这个 getCurrentUser() 函数。
事件
在文件在底部,可以为 body 标签绑定一个 pagecontainershow 事件,这个事件会在页面完全显示以后触发 ... 使用 jQuery 的 on 这个方法去绑定这个事件 ... 事件发生的时候,去执行一个匿名函数 ... 这个函数有两个参数 ... event ,还有 ui ..
$('body').on("pagecontainershow", function (event, ui) {}
在这个函数里,可以使用 jQueryMobile 的 pagecontainer 的 getActivePage 这个方法去获得当前活动的页面。 我们给这个页面一个名字 ... 叫它 currentPage ...
之所以要获得当前活动的页面,是想知道当前活动页面的 id ,这样,我们可以去判断一下,比如当这个活动页面是 user-profile ,也就是用户档案页面的时候,去调用 getCurrentUser 这个函数 ..
这个函数可以去获得当前登录用户的相关的信息,把信息显示在用户档案这个页面上。我们把获取到的当前活动页面的 id 交给 currentPageId 这个变量 ...
然后再用一个 switch 语句 ...
这段代码的意思就是,如果 currentPageId 的值是 user-profile ,也就是当前活动的页面是用户档案这个页面,就会去执行 getCurrentUser 这个函数。
预览
保存,打开浏览器 ... 现在是应用的首页 ... 在控制台上不会显示什么东西 ... 点击右上角的 用户 按钮 .. 会打开 用户档案 页面 ... 这样就会去执行 getCurrentUser ... 这个函数里,定义了把请求返回来的数据输出到了控制台上 ...
在下面的视频里,再去处理一下 ... 在用户没有登录的时候访问用户档案页面,会把用户重定向到用户登录页面。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
02-07)
访问 用户档案 页面,如果用户没有登录的话,可以把用户重定向到 用户登录 页面,登录成功以后,再返回 用户档案 页面。 这个视频我们一起来实现这个功能。
index.js
在 用户档案 页面加载以后,会去执行 getCurrentUser,在这个函数里,我们可以去判断一下获取到的用户的 ID ,如果用户的 id 是 0 的话,说明是匿名用户,也就是没有登录到网站的用户。
如果是这样,可以把用户重定向到用户登录页面,如果用户的 id 不是 0 ,就去把用户的相关信息显示到页面上 ... 先定义几个需要用到的变量 ...
var uid = data.user.uid,
userName = null,
userCreated = null;
然后用一个 if 语句,去判断一下 uid 是不是为 0 .. 如果是,就去执行一个重定向的动作 ... 可以调用 jQueryMobile 的 pagecontainer 的 change 方法 ...
$('body').pagecontainer('change', '#user-login');
要重定向到的地方就是 #user-login ,也就是用户登录页面 ... 如果用户的 uid 不是 0 ,用一个 else ,把这段代码放在这个花括号里 ...
再去修改一下 userLogin 这个函数 ... 当用户成功登录以后,可以把用户重定向到用户档案页面 ..
$('body').pagecontainer('change', '#user-profile');
用户登出
下面,我们可以再去修改一下 用户登出 的代码 ... 先取消之前的注释 ... 然后定义一个函数 ... 叫做 userLogout ... 把这个用户登出的代码放在这个函数里面 ...
登出成功以后 ... 可以把用户重定向到首页上 ...
$('body').pagecontainer('change', '#front');
再去指定一下在什么时候,去执行这个登出的动作 ... 在登出的按钮上,定义了一个 user-logout 的类 ... 用这个类可以获取到这个按钮 .. 再用一个 jQuery 的 click 方法 ... 在方法里面,指定要做的事 ... 就是去执行 userLogout 函数 ...
// 点击页面底部 登出 按钮时执行 userLogout()
$('.user-logout').click(userLogout);
表单的默认行为
提交表单的时候,会有一些默认的行为,我们可以用一个方法防止表单的默认行为 .. 找到页面上的表单 ... 调用 on 方法,给它绑定一个 submit 事件,在表单上发生这个事件的时候,调用事件对象的 preventDefault 方法,可以防止表单的默认行为。
// 防止表单默认的行为
$("form").on("submit", function (event) {
event.preventDefault();
});
预览
保存一下文件 ... 回到浏览器 ... 现在我们在应用的首页上 ... 并且没有登录 ... 点击页面右上角的 用户 图标 ... 页面显示以后会去执行 getCurrentUser .. 因为还没登录 ... 所以会把我重定向到 用户登录 的页面 ...
输入用户名 ... 密码 ... 点击 登录 ... 如果身份验证成功的话 ... 会把我重定向到 用户档案 页面 ... 因为现在已经登录了,所以,在用户档案页面上会显示出我的用户名,还有注册的时间。
点击右下角的 登出 按钮,会退出登录 ... 同时把用户重定向到应用的首页 ... 再打开 用户档案 页面 ...
现在又是匿名用户的身份,也就是用户的 uid 是 0,这样又会把用户重定向到用户登录的页面了 ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
03-01)
在这个课程的开始,我们已经开启了服务的节点资源里面的 retrieve ,用这个服务资源来请求相应的节点,可以返回节点的数据。
这个视频我们介绍一个可以获得一个 JSON 格式的内容列表的方法 ...
其实在 Drupal 上一提到列表,你应该会想到 views 模块,这里我们需要用到的就是 views 视图模块,然后再加上一个 views_datasource 模块。它可以把内容列表,输出成我们需要的 json 格式。
如果你还没下载这个模块的话,可以在这个地址里找到这个模块。https://drupal.org/project/views_datasource
下载好以后把它放在 Drupal 的模块目录的下面。然后打开 模块,在 views 区域里,可以找到 Views JSON ,开启这个模块 ... 点击 保存设置 ..
视图
下面可以去创建一个视图 .. 打开 结构,Views ... 视图 ... 添加一个新的视图 ... 输入视图的名字 ... 叫它 article ... 文章
显示是 内容 ,类型选择 文章,创建一个新的页面, 页面的标题是 文章列表 ... 设置一下页面的路径 ... article-list ...
Display format ,显示格式,选择 JSON data document 。 然后点击 继续并编辑。 在这个列表里,你可以配置一下想要的内容的字段,默认这里只有一个内容的标题 ....
点击 添加 ... 搜索一下 nid ... 这个字段是节点的 id ,一会儿我们需要用到这个字段里的东西 ... 应用 ... 注意要取消一下字段的标签 ....
在下面,可以预览到输出的结果 .. 你会发现文章列表的使用的是 JSON 的形式,整个列表在一个 nodes 里面,每个列表项目里,有一个 title 标题 ... 还有一个 nid ,节点的 id 号。
最后我们需要再做一个特殊的设置,点击 格式 后面的 设置 .. 取消勾选一下 Views API mode 这个选项 ... 这样视图会用纯 JSON 的形式输出这个内容列表 ...
点击 应用 .. . 然后再 保存 一下这个视图。 在浏览器里,打开这个视图页面的地址 ...http://localhost/drupal/article-list
会用 JSON 的形式,显示这个内容的列表。
现在,我们就成功的创建好了应用需要的内容列表的数据。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
03-02)
下面我们一起把前面用视图得到的一个 JSON 格式的内容列表显示到应用的主页上。先定义一个可以载入内容列表的函数,函数做的事就是用 jQuery 的 ajax 方法去请求列表的地址,成功以后用一个 for 循环,把获得的数据输出到页面上。然后再去设置一下在什么情况下去执行这个显示内容列表的函数,可以在页面显示以后,如果活动页面是 front ,也就是首页的时候,去执行它。
loadArticleList
下面先去定义这个显示内容列表的函数,可以叫它 loadArticleList ... 里面用一个简单的 ajax 方法 ... 因为这个请求是一个简单的 GET 请求,不需要去验证 CSRF 。
请求的地址是http://127.0.0.1/drupal/article-list.. 类型是 GET .. 要求返回的数据的类型是 json ,错误的时候,去执行 onError .... 请求成功以后 ... 可以先请求回来的数据先简单的输出到控制台上看一下 ...
/**
* 内容页面
*/
function displayNode(nid) {
$.ajax({
url: 'http://127.0.0.1/drupal/myservice/node/' + nid,
type: 'GET',
dataType: 'json',
error: onError,
success: function (data) {
console.log(data);
}
});
}
调用 loadArticleList
在这个文件的下面,我们在之前的视频里已经用到了 jQueryMobile 的 pagecontainershow 这个事件 ... 它会在页面完全显示以后被触发 ...
在这个 switch 语句里,再去定义一种情况 ... 当活动的页面是 front ,这个 front 是在首页上的那个容器里定义的 ID,也就是如果活动页面是首页的话 ...
去执行一下刚才我们定义的 loadArticleList 这个函数。
case 'front':
loadArticleList();
break;
预览
先保存一下这个文件 ... 回到浏览器 ... 打开应用的首页 ... 在控制台上,你会看到请求成功以后返回来的数据 ... jQuery 已经给我们把数据转换成了 JavaScript 的对象形式...
打开以后,里面是一个 nodes 属性 .. 这个 nodes 属性的值是一个数组 ... 再打开里面的一个数组项目... 每个数组项目里都有一个 node 属性,node 在 Drupal 里就是内容的意思。
这个属性的值又是一个对象,在这个 node 对象里,有我们想要的 nid ,内容的 id 号,还有 title,内容的标题...
循环
下面再回到应用项目... 可以先看一下应用的首页的 html ,打开 index.html,这个 id 是 front 的 div 容器就是应用的首页。在这个页面的主体部分里面,我添加了一个空白的 ul 标签,这个标签上定义了 article-list 这个 id ,可以使用这个 id 来定位这个 ul 容器,通过代码把想要的东西添加到这个容器里。
这个 ul 无序列表,用到了 jQueryMobile 的 listview 。
回到 index.js ... 在 loadArticleList 这个函数里,请求成功以后要做的事情里面 ... 先定义几个一会要用到的变量 ...
var i,
nodes = data.nodes,
articleList = document.getElementById('article-list');
下面再用一个传统的 for 语句,去输出得到的数据 ... 在这个 for 循环里面 ... 设置 articleList 的 innerHTML ,也就是它的内部的 html 内容。这个 articleList 就是用来显示文章列表的那个无序列表容器。
每次循环的时候,就把一组内容是 内容标题 的列表,添加到这个容器里面。
for (i = 0; i < nodes.length; i += 1) {
// console.log(data.nodes[i].node.title);
articleList.innerHTML +=
'<li><a href="#node" class="node-title" data-nid=' +
nodes[i].node.nid + '>' +
nodes[i].node.title +
'</a></li>';
}
输出内容的标题,我们用了一个 nodes[i].node.title ... nodes 是在前面定义的变量 ... 它其实是 data.nodes ...
往 jQueryMobile 的列表视图里添加了新的项目以后,我们需要刷新一下它才能够正常的显示 .. 可以调用 listview 的 refresh 方法 ...
// 刷新列表视图
$('#article-list').listview('refresh');
预览
保存 ... 回到浏览器 ... 打开应用的首页 ... 然后刷新一下 ... 如果一切都成功的话,会在首页上显示出内容的列表 ... 这个内容的列表里数据是通过 views_datasource 模块创建的。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
03-03)
这个视频我们去创建一个内容页面,在点击内容列表里的某个内容的时候,会打开这个内容页面,在这个页面上显示具体的东西,比如内容的标题,正文,作者等等。
前面我们已经开启了服务的 node retrieve 资源 ,可以使用 myservice/node 再加上节点 id 的形式来请求指定节点上的内容。
在内容列表里,可以添加一个 data-nid 的属性,然后在点击内容列表里的内容标题的时候,获取到这个 data-nid 属性的值,也就是节点的 id。
事先定义一个可以显示内容的函数,点击标题去执行这个函数,同时把 nid 作为调用这个函数的一个参数,这样在显示内容的这个函数里,可以利用这个 id ,这样使用 myservice/node 加上这个 id ,就可以得到对应的节点内容了。
检查服务资源
先打开 Drupal 网站,结构,服务,编辑一下 myservice,确定在这里已经勾选了 node 里面的 retrieve ....
index.html
再回到应用项目 .. 打开 index.html ,我事先在添加了一个新的页面,就是这个内容页面。页面的 id 是 node,在页面的头部,有一个空白的 h1 标签,上面有一个 node-page-title 类, 一会儿可以把内容的标题放在这个容器里。
页面的主体部分上,有一组 div 标签,上面添加了一个 node-page-body 类。
index.js
打开 index.js 。先去定义一个用来显示内容的函数 ... 可以叫它 displayNode ... 这个函数可以授受一个 nid 参数 ... 在这个函数里面,使用 jQuery 的 ajax 方法,去请求相应的内容 ...
这个请求的地址是网站的服务地址,后面加上 node ,再加上节点的 id ,这个 nid 会在调用这个 displayNode 函数的时候传递过来。也就是我们点击了哪个内容,这个 nid 就会是哪个内容的 id 。
请求的类型是 GET,数据的类型是 json ... 请求成功以后,把请求得到的数据输出到控制台上 ...
调用 displayNode
下面,我们要决定在什么情况下去调用这个显示节点的函数。在显示内容列表这个函数里 ... 先去改造一下输出的列表项目 ... 修改一下列表项目链接的地址 ... #node ,这样点击列表标题,会打开显示内容的页面 ...
再添加一个 node-title 类 .. 一会儿要用到它给标题绑定一个点击的事件 ... 再添加一个 data-nid 属性 ... 这个属性是我们自己定义的 ... 属性的值就是节点的 id 号。
'<li><a href="#node" class="node-title" data-nid=' +
nodes[i].node.nid + '>' +
nodes[i].node.title +
'</a></li>';
下面去给 node-title 绑定一个点击事件,点击以后,先获得所点击 data-nid 属性的值,这个值就是节点的 id ,然后把这个 id 作为一个参数,去调用显示内容的函数。
// 得到所点击的节点的 id
$('.node-title').click(function () {
var nid = $(this).attr('data-nid');
displayNode(nid);
});
预览
下面先去预览一下 ... 保存文件 .. 打开浏览器 ... 刷新一下 ... 然后点击首页上的内容列表里的某个内容的标题 ... 它会触发点击事件,获取到 data-nid 属性的值,再用这个值作为一个参数,去调用显示内容的 displayNode 函数 ...
在控制台上,你会看到所点击的这个节点的相关数据 。 打开这个数据对象 ... 你可以自己决定使用这里面的哪一些内容 ..
比如,我们可以在内容的页面上先输出内容的标题 .... 标题的内容在 title 这个属性里面 ..
index.js
回到应用项目 ... 找到 displayNode 这个函数 ... 先获取到想要显示内容标题的地方 .. 再调用 html 方法,去设置一下里面的内容 ...
内容是在 data 这个对象的 title 属性里面 .. $('.node-page-title').html(data.title);
下面再去找到内容的正文 .. (#浏览器) 正文的内容是在 body 这个对象里面 ... und 这个数组 .. 数组里的第 1 个项目 ... 项目里的 safe_value 应该就是我们想要的内容正文了。
回到 index.js ... 找到想要显示正文的容器 ... 调用它的 html 方法 ... 设置一下里面的内容 ...
$('.node-page-body').html(data.body.und[0].safe_value);
预览
保存 ... 下面再回到浏览器上预览一下 ... 回到首页 ... 刷新一下 ... 点击列表里的一个项目 ... 会打开内容页面 ... 在内容的页面上,可以显示出所点击的具体的内容。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
03-04)
现在我们已经做好了内容的列表页面,还有显示内容的页面。点击列表页面里的某个内容的标题,可以打开相应的内容页面来显示这个内容。
问题
不过如果这个时候,刷新一下浏览器的话,你会发现,内容页面上就不会再显示内容了。这是因为,在点击列表里的标题的时候,会执行 displayNode 这个用来显示内容的函数,并且会把所点击的内容的 id 作为调用这个函数时候的参数。
这样,在 displayNode 函数里面,可以根据这个 id 发送对应的请求,找到相应的内容。不过如果直接在内容页面刷新的话,就不会再显示内容了。因为没有执行 displayNode 函数 ... 执行这个函数也需要对应的节点 id 做为参数才能显示正确的内容。
解决方案
解决这个问题的方法可以这样... 在点击内容列表的时候,不去立即执行显示内容的函数,而是把当前点击的节点 id 存储到用户的浏览器里面,然后在内容页面显示的时候,先获取到存储在浏览器里的节点 id ,再用这个 id 作为参数去执行显示内容的函数。
这样即使我们再次的刷新页面 ... 也会先读取到浏览器里存储的节点 id ,然去调用显示内容的函数。也会显示出正确的内容。
实施
找到 loadArticleList 这个函数 ... 先注释掉执行 displayNode 函数的这行代码 ... 在这里,我们设置一下去存储当前点击的节点 id 到浏览器里面 ...
可以使用 localStorage ... 调用它的 setItem 去设置想要存储的东西 ... 可以先命名一下存储的数据的名字 ... 这里我们叫它 currentNode ... 具体要存储的值,就是上面获取到的节点的 id ...
localStorage.setItem("currentNode", nid);
再浏览到文件的底部 ... 先定义一个变量 .... 获取到存储在浏览器上的 currentNode ... 也就是用户所点击的节点的 id ...
currentNode = localStorage.getItem('currentNode');
然后在后面的 switch 语句里面,判断一下当前活动的页面是不是 node ,也就是显示内容的页面 ... 如果是的话 ... 判断一下 currentNode 是否有值 ... 如果有 ... 就去执行 displayNode 这个函数来显示内容 ... 调用它的时候,把获取到的存储在浏览器里面的节点 id 作为它的参数 ...
case 'node':
if (currentNode) {
displayNode(currentNode);
}
break;
预览
保存一下 ... 回到浏览器 ... 先回到应用的首页,刷新一下 ... 点击打开一个内容 ... 会在内容页面显示它 ... 打开 chrome 浏览器的开发者工具,打开资源选项卡,Local Storge ,在这里,你会看到存储在浏览器上的 currentNode ,还有它的值 ...
刷新一下 ... 现在,页面上仍然会显示这个内容 .. . 因为我们设置了,在刷新页面内容页面以后,去读取 currentNode 里的值,根据这个值,去调用显示内容的函数 ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
03-05)
现在,这个应用有个小 bug ,点击打开一个内容 ... 然后再返回到内容的首页上 ... 这个内容列表会重复显示 ...
修复的方法就是,在浏览首页的时候,先把内容列表容器设置为空白的 .. 然后再去调用加载内容列表的函数 ...
这样就不会重复去显示了 ..
打开应用的 index.js
在文件的底部 ... 在 当前页面是 front 这种情况下 ... 先获取到内容列表的容器 .... 再去调用 html 方法 .. 设置一下里面的内容为空白的内容 ...
保存 ...
再回到应用的项目页面 ... 刷新 一下 .. 打开一个内容 ... 再回到应用的首页 ...
现在这个内容列表就不会再重复显示了 ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
03-06)
用户打开某个具体的内容页面以后,点击页面下方的 编辑 按钮,可以打开编辑页面去编辑当前这个内容。我们要做的就是去创建一个这样的编辑页面,点击编辑。。。动态的去获取到要编辑的内容,把对应的内容放在相应的表单元素里 ... 用户修改以后,点击 更新 .. 可以把保存所做的修改 ...
想要编辑内容需要开启服务的 node 里面的 update 资源 ...
确定开始了这个资源以后 ...
index.html
打开应用项目的 index.html ,这里我添加了一个 编辑内容 的页面 ... 页面上定义了 node-edit 这个 id ... 页面的主体内容是一个表单 ... 表单里有一个修改内容标题用的文本框 ,上面定义了 node-edit-title 这个 id ...
还有一个用来修改内容主体内容的的文本区域 ... 上面定义了 node-edit-body 这个id ... 最后,还有一个 更新 按钮 ... 上面定义了 node-edit-submit 这个 id 。
editNode
先去定义一个函数,它的作用就是,得到想要编辑的内容的标题还有正文,把标题和正文的内容放在编辑内容页面的标题和正文表单里面 .. 可以叫它 editNode ... 这个函数可以接收一个 nid ,也就是节点 id 的参数 ... 在函数里面用一个 ajax 方法,请求的地址是 url: 'http://127.0.0.1/drupal/myservice/node/' + nid,
类型是 GET ,数据的类型是 json ,错误的时候去执行 onError ... 请求成功的以后 ... 先获取到节点标题的内容,把它放在节点标题表单里 ... 这个节点标题表单元素上,定义了 node-edit-title 这个 id ...
再得到节点正文这个表单元素 ... 把节点的正文内容放在这个文本区域里面 ...
下面在控制台上可以输出点东西 .. 然后我们要做的就是,当用户修改完成以后,点击了 更新 按钮以后,需要收集标题和正文表单里的内容,把它们发送给服务,为我们去更新内容。
先获得 更新 按钮 ... 调用 click 方法,点击它的时候去做一些事情 ... 把标题表单里的内容交给一个变量,叫做,nodeTitle ...
再把正文文件区域里的内容交给一个变量,叫做 nodeBody ...
nodeEditSubmit
下面,我们还需要去定义一个函数,这个函数可以去完成更新的动作 ... 比如我们可以叫它 nodeEditSubmit .. 在点击 更新 按钮的时候,去调用这个函数... 调用的时候,需要几个参数 ... nodeTitle ... nodeBody .. 还有 nid ..
在上面,去定义一下这个 nodeEditSubmit 函数 ...
函数需要接收三个参数 ... nodeTitle 更新之后的节点的标题 ... nodeBody.. 更新以后的节点的正文 ... 还有节点的 id ...
这个函数同样使用 ajax 方法发送一个请求。这个请求需要用到 CSRFToken ...
请求的地址是 'http://127.0.0.1/drupal/myservice/node/' + nid, 类型是 PUT .. dataType 是 json ...
在这个请求里,要添加一个 data 属性 ... 也就是需要向服务器发送的数据 ...
data: 'node[title]=' + nodeTitle + '&node[body][und][0][value]=' + nodeBody,
它的意思就是发送的 node 节点的标题是 nodeTitle ... 还有 node 的 body 的值,也就是正文是 nodeBody ... nodeTitle 还有 nodeBody 是调用这个函数的时候传递过来的 ...
成功以后 ... 在控制台上输出点东西 ... 再把页面重定向到内容页面 ... $('body').pagecontainer('change', '#node');
执行 editNode
最后,我们要做的就是给之前定义的 editNode 函数找一个执行它的地方 .. 在文件的底部 ... 添加一种情况 ...
case 'node-edit':
if (currentNode) {
editNode(currentNode);
}
break;
如果当前页面是 node-edit ... 也就是节点编辑页面的话 ... 就去执行 editNode 这个函数 ... 执行的时候,把存储在本地的当前的节点 id 做为它的参数 ...
预览
保存一下 ... 回到浏览器 ... 刷新 ... 打开一个内容 ... 然后点击 编辑 按钮 ... 会打开编辑内容的页面 ... 获取当前节点的 id ,再去调用 editNode 函数 .. 把节点内容放在编辑的表单里 ...
随便修改一下内容 ... 然后点击 更新 ... 这样会调用 nodeEditSubmit 函数 ... 会把修改以后的内容发送给服务器 ...
成功以后,会返回到编辑的这个内容。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
03-07)
创建内容的页面跟编辑内容的页面是差不多的,这个视频我们为应用添加一个创建内容的功能。先去开启一下服务的 node 里面的 create 资源 ...
index.html
然后去看一下新添加的这个创建内容的页面 ... 页面上定义了一个 node-create ID ... 页面主体部分是一个表单,这个表单跟编辑内容页面上的表单是差不多的 .. 只不过,在表单元素上定义的 id 不太一样 ..
一个标题的文本框 ,上面的 id 是 node-create-title ... 一个正文的文本区域 ... 上面的 id 是 node-create-body ...
最后还有一个 提交 按钮 .. 上面有一个 node-create-submit ID ..
index.js
下面打开 index.js ... 创建一个可以创建内容的函数 ... 函数的名字是 nodeCreate ... 在函数里面先获取到用户在标题和正文里输入的内容 ...
var nodeTitle = $('#node-create-title').val(),
nodeBody = $('#node-create-body').val();
然后用一个 ajax 方法向服务器去发送这些内容 ... 这个请求同样需要一个 CSRFToken ...
请求的地址是http://127.0.0.1/drupal/myservice/node/ ... 类型是 POST ... 数据的类型是 json .. 在这个请求里同样需要一个 data 属性,在这里去定义往服务器上发送的数据 ...
这里需要使用一个特定的格式 .. data: 'node[type]=article&node[title]=' + nodeTitle + '&node[body][und][0][value]=' + nodeBody,
它的意思就是,内容的类型是 article ... 内容的标题是 nodeTitle,也就是在标题文本框里输入的东西 ... 另外还有一个内容的 body ... 也就是内容的正文数据 ...
请求成功以后 ... 在控制台上输出点东西 .. 然后设置一下本地存储的 currentNode ,当前的节点为新创建的这个节点的 id 号
localStorage.setItem("currentNode", data.nid);
然后再重定向页面到显示内容的页面上 ...
调用 nodeCreate
下面我们还是要找一个地方去调它这个创建内容的函数 .. 在一般的页面底部,都有一个创建内容的按钮 .. 点击这个按钮会打开创建内容的页面,在文件的底部,再去添加一种情况 ...
如果当前活动页面是内容创建页面 ... 就去给页面上的 提交 按钮绑定一个点击事件 ... 点击 提交按钮以后,去执行 nodeCreate 这个函数 ...
case 'node-create':
$('#node-create-submit').click(nodeCreate);
break;
}
测试
保存文件 ... 回到浏览器 ... 先刷新一下 ... 然后点击页面底部的 创建 内容按钮 ... 这会打开创建内容的页面 ...
输入标题 .... 正文 ... 然后点击 提交 ...
成功以后,会返回创建的这个内容的页面 .... 再回到内容列表的页面上 ...
同样,你会看到刚才创建的内容 ...
打开 Drupal 网站 ... 在这里,你也会发现刚才创建的内容 。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
03-08)
在显示内容的页面上,点击 删除 按钮,可以删除当前显示的内容。想要通过服务删除内容,需要启用服务的 node 里面的 delete ...
index.js
下面去定义一个可以删除内容的函数 .. . 可以叫做 deleteNode ... 函数可以接收一个 nid 参数 ... 这执行这个函数的时候,需要传递节点的 id 号给这个函数,这样才能删除对应的内容。
在函数里面,同样是用 ajax 方法发送请求 ... 这个删除的请求需要一个 CSRFToken ...
请求的地址是 'http://127.0.0.1/drupal/myservice/node/' + nid, 后面这个 nid 是执行这个函数的时候传递过来的 ..
请求的类型是 DELETE ... 数据类型是 json .. 发生错误去执行 onError ... 请求成功以后 ... 把页面重定向到应用的首页 ...
然后再设置一下在控制台上显示的东西 ...
调用 deleteNode
下面再去找一个地方去调用这个 deleteNode 函数 ... 在显示内容以后,可以去给 删除 内容的按钮绑定一个点击事件 ... 点击 删除 按钮,让它去执行这个 deleteNode 函数 ...
显示内容的功能是在 displayNode 这个函数里定义的 ..
// 删除内容
$('.node-delete').click(function () {
deleteNode(data.nid);
});
调用这个函数的时候,需要把当前显示的节点的 id 传递给这个函数。
测试
保存 ... 回到浏览器 ... 刷新 ... 打开一个内容 ... 内容显示以后 ... 点击页面底部的这个 删除 按钮 ...
这样会成功的删除掉这个内容 ...
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
04-01)
现在我们的应用基本上就做好了,不过为了测试,还是尽量保持应用里的逻辑简单一些 .. 还有很多地方需要改善 ... 但不管怎么样,它已经是一个可以使用的简单的小应用了。在以后的课程里,我们会不断地去完善,做出更好的应用。
下面我们可以使用 PhoneGap ,把它包装成可以直接安装在移动设备上的本地的应用程序 ... 使用 PhoneGap ,你可以参考宁皓网的 PhoneGap 应用开发基础 这个课程。
打开终端工具,Windows 用户可以使用命令行工具,或者 PowerShell ... 进入到桌面上 ... 然后使用 phonegap create 命令,去创建一个应用 ... 应用的名字是 movietalk ..
phonegap create movietalk net.ninghao.movetalk movietalk
创建成功以后,进入到这个应用项目所在的目录 ...
下面我们需要把之前设计好的小应用,用到的一些东西,复制到刚才创建的这个空白的应用模板的目录里面 。
复制一下里面的 index.html .. 应用的页面 ... jqm 目录 ... 也就是 jquerymobile ... 还有 js 这个目录 ...
再打开刚才创建的空白的应用 ... 在桌面上 ... movietalk ... 再打开 www 这个目录 ... 粘贴到这个目录下面。 替换一下 ..
回到终端工具,再去编译一下 ... 把这个应用编译成 ios 平台上运行的应用程序 .. 你也可以把它编译成能在 android 平台上运行的应用。
用一个 phonegap run ios --emulator 命令 .. 编译并安装在iOS 设备的模拟器上 ...
状态栏
这里会有一个问题,就是 iOS 的状态栏会叠加在应用的界面上显示 .. 解决这个问题可以去修改一下 iOS 应用项目的代码。 打开应用所在的目录 ...
在 platforms 这个目录的下面,可以找到编译好的 ios 应用项目 ... 打开 ios 目录 ,再打开里面的这个 xcode 项目文件 ...
在左边的导航这里,打开 Classes ... MainViewController.m.. 找到 viewDidLoad 这段代码 ... 然后可以使用课程资源包里的这段代码,覆盖一下 ...
保存 ... 再点一下运行 ...
现在,状态栏就不会叠加到应用的界面上了 ...
演示
打开这个应用以后,你会看到一个内容列表 ... 点击右上角的 用户 按钮 ... 会提示登录 ... 输入用户名 .. 密码 .. 然后点击 登录 ..
成功以后,会显示当前登录用户的信息 ... 回到应用首页 ... 点击打开一个内容 ... 会在内容页面显示这个内容 ...
点击 删除 按钮 ... 可以删除这个内容 ... 点击 编辑,可以编辑当前显示的这个内容 ... 点击 添加 .. 可以添加新的内容 ...
输入内容的标题 .... 正文 ... 点击 提交 ...
成功以后,会返回到新创建的这个内容的上面。 再回到应用的首页 ... 在这个列表页面上,也会显示出新创建的内容的标题 ...
我们可以再打开 Drupal 网站去看一下 ... 在网站上,你同样也可以看到使用应用新创建的内容。
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
if ([[[UIDevice currentDevice] systemVersion] floatValue] >= 7) {
CGRect viewBounds = [self.webView bounds];
viewBounds.origin.y = 20;
viewBounds.size.height = viewBounds.size.height - 20;
self.webView.frame = viewBounds;
}
self.view.backgroundColor = [UIColor colorWithHue:0 saturation:0 brightness:0.11 alpha:1.0];
}
-(UIStatusBarStyle)preferredStatusBarStyle{
return UIStatusBarStyleLightContent;
}