ionic angularjs $Resource 前端和nodejs后台配合的服务

xiaoxiao2021-02-28  76

本讲解案例于nodejs框架编写的服务端和ionic与angular编写的前端,说明$Resource 服务和服务端是如何打交道的

功能介绍:通过Resource服务和服务器端打交道,获取数据库中的相关数据

数据库使用mongodb

1.ionic angularjs

1.1 ionic前端 H5和js代码

前端代码展现的是俩个select单选框,

<div class="list"> <label class="item item-input item-select" data-tap-disabled="true"> <div class="input-label"> 酒窖编号 </div> <select ng-model="selectedCellar" ng-options="cellar.name for cellar in cellars" ng-change="selectCellarChange(selectedCellar)"></select> </label> <label class="item item-input item-select" data-tap-disabled="true"> <div class="input-label"> 区域编号 </div> <select ng-model="selectedArea" ng-options="area.areaname for area in areas" ng-change="selectAreaChange(selectedArea)"></select> </label> </div>

1.2 controller

控制器中设置了下拉刷新,下拉刷新的同时使用Cellars自定义service向服务器请求相关数据。

$scope.doRefresh = function () { $scope.cellars = undefined;//清空已选择记录 $scope.areas = undefined; //下面的方法就是调用iotservices中的方法 Cellars.query(function (cellars) { $scope.$broadcast('scroll.refreshComplete'); if (cellars.error) { $window.alert('Retrieve cellars list failed!'); return;//以下不执行 } $scope.cellars = cellars;//正确就执行赋值语句,将请求到的cellars赋值出来。 console.log(cellars); }, function () { $scope.$broadcast('scroll.refreshComplete'); $window.alert('Retrieve device list failed!'); }); }; $scope.areas = []; $scope.selectCellarChange = function (selectedCellar) { Areas.query({ "name": selectedCellar.name }, function (areas) { if (areas.error) { $window.alert('Retrieve cellars list failed!'); return; } $scope.areas = areas; console.log(areas); }, function () { $window.alert('Retrieve device list failed!'); }); }

1.3 angularjs自定义服务

这里使用了$resource这个服务,可以创建一个资源对象Cellars,可以把Cellars对象理解成同RESTful的后端服务进行交互的接口,在控制器中Cellars.query就是使用了这个资源对象

angular.module('starter.iotservices', []) .factory('Cellars', ['$resource', '$http', '$window','Settings', function ($resource, $http, Settings) { var Server = Settings.httpServer; return $resource('api/admin/cellar/:id', { id: '@cellarid' }, { }) }]) .factory('Areas', ['$resource', '$http', '$window', 'Settings', function ($resource, $http, Settings) { var Server = Settings.httpServer; return $resource('api/admin/area?name=:name', { name: '@cellarname' }, { }); }])

这里我就可以先介绍一下$Resource

1.3.1 get

表达式不定义具体的参数,get()请求一般被用来获取单个资源。

get(params,successFn,errrorFn) //GET /api/users nodejs服务器中get请求的编程方式 Cellars.get(function(resp){ //处理成功 },function(err){ //处理错误 });

如果参数中传入了具名参数(例子中的参数是id),那么get()方法会向包含id的URL(这个在nodejs服务端中)发送请求:

//向nodejs服务器routes发起一个请求:GET-->/api/users/123 User.get({id:'1'},function(resp){ //success },function(error){ //fail });

1.3.2 query 请求:

query向指定URL发送一个GET请求,并期望返回一个JSON格式的资源对象集合。 query()和get()方法之间唯一的区别是AngularJS期望query()方法返回数组。

//发起一个请求,上面的控制器就是这个 Cellars.query(function(cellars){ //读取集合中的所有对象 $scope cellars=cellars; });

1.3.3 save 请求:

save(params, payload, successFn, errorFn)

save方法向指定URL发送一个POST请求,并用数据体来生成请求体。save()方法用来在服务器上生成一个新的资源。 payload:代表请求发送的数据体.下面是创建一个酒窖区域Area的后台处理方法,数据体就是用户定义的酒窖区域name,

//发送一个请求 with the body { "areaname": $scope.area.areaname } $scope.createArea = function (area) { if (!$scope.area.areaname) { $window.alert('area name is required!'); return; } Areas.save({ name: $scope.cur_wc }, { "areaname": $scope.area.areaname }, function (resp) { if (resp.err) { $window.alert(resp.err); return; } $scope.hideModal(); $scope.actionwc.push(resp); }, function () { $window.alert('Create area failed! Please try again later.'); }); };

1.3.4 delete 请求:

请求处理方式如下

delete(params, payload, successFn, errorFn)

delete方法会向指定URL发送一个DELETE请求,并用数据体来生成请求体。它被用来在服务器上删除一个实例:

// DELETE /api/users User.delete({}, { id: '123'//删除id为123的数据体 }, function(response) { // 处理成功的删除响应 }, function(response) { // 处理非成功的删除响应 });

1.3.5 remove 请求:

请求处理方式如下,这个东西是在nodejs中编写的 remove方法和delete()方法的作用是完全相同的,它存在的意义是因为delete是JavaScript的保留字,在IE浏览器中会导致额外的问题。

remove(params, payload, successFn, errorFn) // 发起一个请求: // DELETE /api/users User.remove({}, { id: '123' //删除id为123的使用者 }, function(response) { // 处理成功的删除响应 }, function(response) { // 处理非成功的删除响应 });

2. 实例解释:通过resource服务进行酒窖和区域的save和delete操作

2.1 post请求创建酒窖cellars:

2.1.1前端:

<form ng-submit="createWc()" class="form-horizontal"> <div class="form-group"> <label class="col-sm-4 control-label">酒窖名称 </label> <div class="col-sm-6"> <input ng-model="winecell.name" type="text" class="form-control" required placeholder="Winecell Name"> </div> </div> <div class="form-group"> <div class="col-sm-6 col-sm-offset-4"> <div class="btn-group pull-right"> <button type="submit" class="btn btn-primary">创建</button> <button type="button" class="btn btn-default" data-dismiss="modal">关闭</button>

2.1.2控制器处理,用到post方法:

$scope.createWc = function () { if (!$scope.winecell.name) { $window.alert('Device name is required!'); return;//下面将不会被执行 } if (Winecells.post({ "name": $scope.winecell.name })) { $scope.hideModal(); } else $window.alert('Create device failed! Please try again later.'); };

2.1.3 后台service.js进行处理,连接到api进行处理,Winecells是自定义服务,$resource注入的angular服务:

angular.module('iotgo'). factory('Winecells', ['$resource','$http','$window', function ($resource,$http) { return $resource('/api/admin/cellar/:id', {id:'@cellarid'}, { post:{method:'POST'} });

如果参数中传入了具名参数(我们例子中的参数是id),那么post()方法会向包含id的URL发送请求,注意上面代码中的”@cellarid”,使用了@后,当执行post时,向/api/admin/cellar/:cellarid路由发送请求。

2.1 .4 mongodb数据库中的配置 和 后台api路由处理cellars:

*mongodb数据库中的配置

nodejs db文件夹下

index.js文件

exports.Cellar = Cellar;//路径是db/index,在api中用到的 var Cellar = require('./cellar');// var Area = require('./area'); var mongoose = require('mongoose');

cellar.js文件 这就是和本地mongodb数据库的交互操作了

var mongoose = require('mongoose'); var uuid = require('uuid'); var Schema = mongoose.Schema; var now = function () { return new Date(); }; var incCellarid = function(cellarid){ var cellarid = (parseInt(cellarid.substr(0), 16) + 1).toString(16); if (cellarid.length > 3) { return false; } if (cellarid.length < 3) { cellarid = '000'.substr(cellarid.length) + cellarid; } return cellarid; }; // Exports var schema = new Schema({ name: { type: String, unique: true }, cellarid: { type: String, require: true, index: true, match: /^[0-9a-f]{3}/ }, apikey: { type: String, unique: true, default: uuid.v4 }, createdAt: { type: Date, index: true, default: now } }); schema.static('exists', function(name, callback){ this.where('name', name).findOne(callback); }); schema.static('getNextCellarId', function(name, callback){ this.where('name').select('cellarid').sort('-cellarid').findOne(function(err, cellar){ if(err) { callback(err); return; } var cellarid; if(! cellar) { cellarid = "001"; callback(null, cellarid); return; } cellarid = incCellarid(cellar.cellarid); if(! cellarid){ callback('Not enough device ids available!'); return; } callback(null, cellarid); }); }); schema.static('getCellarByCellarid', function(cellarid, callback){ this.where('cellarid', cellarid).findOne(function(err, cellar){ if(err) { callback(err); return; } callback(null, cellar); }); }); module.exports = mongoose.model('Cellar', schema);

* api 对数据库调用的操作在这里getCellarByCellarid函数在db,cellar.js中定义

/api/admin/cellar//:cellarid

var express = require('express'); var db = require('../../db/index');//请求数据库了 var Cellar = db.Cellar; .post(function(req, res){ Cellar.getCellarByCellarid(req.params.cellarid, function(err, cellar){ if(err || ! cellar) { res.send({ err: "Cellar dose not exist." }); return; } cellar.name = req.body.name; cellar.save(function(err, cellar){ if(err){ res.send({ err: "Save cellar failed." }); return; } res.send(cellar); }); }); })
转载请注明原文地址: https://www.6miu.com/read-78998.html

最新回复(0)