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

本讲解案例于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);
    });
  });
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值