你的位置:首页 > Java教程

[Java教程]AngularJS订阅API服务


 

本篇使用AngularJS实现订阅某个API服务。

首页大致是:

 

其中,what's on显示首页内容,Search通过输入关键词调用API服务显示到页面,MyShows显示订阅的内容。

Sarch页界面如下:

 

通过在搜索框中输入关键词,把查询到信息显示在当前页面,并且可以点击订阅和取消订阅按钮。

My Shows页界面如下:

 

显示订阅的内容,并且提供取消订阅按钮。

首先,需要了解API提供方所要求的格式。大致是:http://api.themoviedb.org/3/search/tv?api_key=87de9079e74c828116acce677f6f255b&query=Star%20Trek

文件结构:



node_modules/ [通过node下载的module存放于此]
sections/
.....my-shows/
..........my-shows.ctrl.js
..........my-shows.tpl.html
.....search/
..........search.css
..........search.ctrl.js
..........search.tpl.html
.....show/
..........show.ctrl.js
..........show.tpl.html
.....whats-on/
..........whats-on.ctrl.js
..........whats-on.tpl.html
services/
.....show.fct.js [search页需要的查询服务封装在这里]
.....store.fct.js [search需要的操作服务封装在这里]
app.core.js
app.js
app.routes.js [设置路由]
app.services.js
index.html

各个module之间的关系是重中之重,如下:

 

 

通过node需要安装的module命令如下:

npm install bootstrap
npm install angular
npm install angular-route
npm install angular-animate
npm i angular-local-storage

index.html

 

<a href="#/">What's on</a><a href="#/my-shows">My Shows</a><a href="#/search">Search</a><main ng-view=""></main><!--js引用-->angular.min.jsangular-route.min.jsangular-animate.min.jsangular-local-storage.min.jsui-bootstrap-tpls-0.12.1.min.jsapp.jsapp.core.jsapp.routes.jsapp.services.js<!--SERVICES-->show.fct.jsstore.fct.js<!--CONTROLLERS-->my-shows.ctrl.jssearch.ctrl.jsshow.ctrl.jswhats-on.ctrl.js

 

 

app.routes.js



在这里设置路由。

 

angular.module('app.routes',['ngRoute'])  .config(routes);function routes($routeProvider){  $routeProvider    .when('/',{      templateUrl: 'sections/whats-on/whats-on.tpl.html',      controller:'WhatsOnController',      controllerAs: 'whatsOn'    })    .when('/my-shows',{      templateUrl: 'sections/my-shows/my-shows.tpl.html',      controller: 'MyShowsController',      controllerAs: 'myShows'    })    .when('/search',{      templateUrl: 'sections/search/search.tpl.html',      controller: 'SearchController',      controllerAs: 'search'    })    .when('/show/:id',{      templateUrl: 'sections/show/show.tpl.html',      controller: 'ShowController',      controllerAs: 'show'    })    .otherwise({      redirectTo: '/'    });}

 

show.fct.js



在这里,通过factory的方式返回一个对象,该对象包含查询的方法。

 

angular  .module('app.services')  .constant('API_KEY', '87de9079e74c828116acce677f6f255b')  .constant('BASE_URL', 'http://api.themoviedb.org/3')  .factory('ShowService', dataService);function dataService($http, API_KEY, BASE_URL, $log) {  var data = {    'get': get, //使用的时候不带参数    'search': search  };  //经$http返回的是一个promise  function makeRequest(url, params) {    var requestUrl = BASE_URL + '/' + url + '?api_key=' + API_KEY;    //遍历查询参数    angular.forEach(params, function (value, key) {      requestUrl = requestUrl + '&' + key + '=' + value;    });    //发出请求    //$http接受一个对象也是第一次见    return $http({      'url': requestUrl,      'method': 'GET',      'headers': {        'Content-Type': 'application/json'      },      'cache': true    }).then(function (response) {      return response.data;    }).catch(dataServiceError);//旦凡一个函数作为令一个函数的实参,这两个函数的参赛也进行了传递  }  //定义的时候带参数  function get(id) {    return makeRequest('tv/' + id, {});  }  //查询  function search(query){    return makeRequest("search/tv",{query:query}).then(function(data){      return data.results;    });  }  function dataServiceError(errorResponse) {    $log.error('XHR Failed for ShowService');    $log.error(errorResponse);    return errorResponse;  }  //factory返回的就是一个对象  return data;}

 


以上,在makeRequest方法中,不仅可以对url进行拼接,还对查询字符串(以对象的形式)进行了拼接。发出请求返回的是promise,即在调用的时候还可以使用then方法。

store.fct.js



这里封装了订阅和取消订阅的操作。

 

angular  .module('app.services')  .factory('StoreFactory', dataService);function dataService(localStorageService){  var _shows = [];  var ls = localStorageService.get('store');  if(ls !== null){    _shows = ls;  }  var service = {    'addShow':addShow,    'getShow':getShow,    'getShows':getShows,    'removeShow':removeShow  };  //订阅  function addShow(data){    _shows.push(data);    save();  }  function getShow(id){    var result=false;    angular.forEach(_shows, function(show){      if(result===false){        if(show.id===id){          result = show;        }      }    });    return result;  }  function getShows(){    return _shows;  }  //取消订阅  function removeShow(id){    var idx=-1;    var found=false;    angular.forEach(_shows, function(show){      if(found === false){        if(show.id === id){          found=true;        }        idx++;      }    });    if(found === true){      _shows.splice(idx, 1);      save();    }  }  //保存到本地  function save(){    localStorageService.set('store',_shows);  }  return service;}

 

所以,所谓的订阅就是把获取到的数据保存在某个地方,取消订阅就是把数据从某个地方删除。

search.ctrl.js

 

 

angular.module('app.core').controller('SearchController', function (ShowService, $timeout, StoreFactory) {  var vm = this;  vm.results = false;  vm.searching = false;  vm.query = function (query) {    vm.searching = true;    ShowService.search(query).then(function (response) {      vm.results = response;      $timeout(function(){        vm.searching = false;      },500);    }).catch(function (error) {    });  };  //订阅  vm.trackShow=function(show){    StoreFactory.addShow(show);  }  //取消订阅  vm.unTrackShow = function(id){    StoreFactory.removeShow(id);  }  //根据id搜索本地的store,存在就返回true, 不存在就返回false  vm.hasShow = function(id){    return (StoreFactory.getShow(id) !== false);  }});

 

search.tpl.html

<input type="text" name="query" ng-model="query"/><p ng-show="search.searching">Perfoming search...</p><button ng-click="search.query(query)">Search</button><ul>  <li ng-repeat="show in search.results track by show.id">    ...    <div ng-switch="search.hasShow(show.id)">      ...      <button ng-switch-when="false" ng-click="search.trackShow(show)">Track Show</button>      <button ng-switch-when="true" ng-click="search.unTrackShow(show.id)">UnTrack Show</button>    </div>  </li>  <li class="no-data" ng-if="search.results === false">Find shows to track by using the search bar above.</li>  <li class="no-data" ng-if="search.results.length == 0">Your search did not return any results, try again.</li></ul>

 

以上,本地存在就显示UnTrack Show按钮,本地不存在就显示Track Show按钮。