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.js
angular-route.min.js
angular-animate.min.js
angular-local-storage.min.js
ui-bootstrap-tpls-0.12.1.min.js

app.js
app.core.js
app.routes.js
app.services.js

<!--SERVICES-->
show.fct.js
store.fct.js

<!--CONTROLLERS-->
my-shows.ctrl.js
search.ctrl.js
show.ctrl.js
whats-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按钮。

时间: 2024-10-11 23:29:27

AngularJS订阅API服务的相关文章

教你3分钟快速开发微信公众号[订阅号][服务号]

Wx-tools是基于微信公众平台API的轻量级框架. 基于Wx-tools你可以开速开发一个订阅号/服务号的web应用后台. GitHub仓库 下载wx-tools-1.0.0.jar API开发文档 大三做过几个基于微信公众平台API的项目,感觉操作太繁琐,有时微信官方开发文档还有错!! 所以!wx-tools诞生了! 看过很多优秀的开源代码,特别是chanjarster的代码,优秀的设计思想让我迷糊灌顶. 不多说,让我带你快速有效可拓展的开发一个订阅号/服务号的后台. 到底有多简单?只需要

AngularJS的核心对象angular上的方法全面解析(AngularJS全局API)

总结一下AngularJS的核心对象angular上的方法,也帮助自己学习一下平时工作中没怎么用到的方法,看能不能提高开发效率.我当前使用的Angularjs版本是1.5.5也是目前最新的稳定版本,不过在全局API上,版本不同也没什么区别. AngularJS 全局 API列表 element bootstrap copy extend merge equals forEach noop bind toJson fromJson identity isUndefined isDefined is

[CI] 使用CodeIgniter框架搭建RESTful API服务

在2011年8月的时候,我写了一篇博客<使用CodeIgniter框架搭建RESTful API服务>,介绍了RESTful的设计概念,以及使用CodeIgniter框架实现RESTful API的方法.转眼两年过去了,REST在这两年里有了很大的改进.我对于前一篇博客中的某些方面不是很满意,所以希望能利用这次机会写一个更加完善的版本.我的项目基于Phil Sturgeon的CodeIgniter REST Server,遵循他自己的DBAD协议.Phil的这个项目很棒,干净利落,简单实用,并

延迟调用或多次调用第三方的Web API服务

当我们调用第三方的Web API服务的时候,不一定每次都是成功的.这时候,我们可能会再多尝试几次,也有可能延迟一段时间再去尝试调用服务. Task的静态方法Delay允许我们延迟执行某个Task,此方法可以让我们做到延迟一段时间再去调用服务:多尝试几次调用如何实现呢?可以用循环遍历. 在"使用HttpClient对ASP.NET Web API服务实现增删改查"中,创建了一个ASP.NET Web API项目,本篇沿用此Web API服务. 在ASP.NET Web API项目的同一个

ServiceStack.Hello——跨平台.net REST api服务搭建

ServiceStack.Hello——跨平台.net REST api服务搭建 自己创建: https://github.com/ServiceStack/ServiceStack/wiki/Create-your-first-webservice 直接下载源码: https://github.com/ServiceStack/ServiceStack.Examples/tree/master/src/ServiceStack.Hello 在VS2013中启动项目: 查看metadata: h

angularjs学习笔记--服务

在angularjs中,服务是一个函数或对象,可在angularjs应用中使用.其中$location服务可以返回当前页面的url地址.要使用它,需要在controller中进行定义,作为一个参数传入到controller中. <!DOCTYPE html> <html lang="en"> <head> <script src="../angular/angular.js"></script> </

Retrofit 2.0 接口API服务代码

接口API服务代码 接口定义有以下的配置方式, 取决于接口的参数需求(使用注解方式标注请求模板接口) // 可以直接在URL中指定参数 @GET("version/android/2.3.0?order=desc") Call<VersionInfoDTO> loadVersionInfo(); // 设置POST请求体 @POST("users/new") void createUser(@Body User user, Callback<Use

演示如何在 WebForm 中提供 web api 服务

Global.asax.cs using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.Routing; using System.Web.Security; using System.Web.SessionState; using System.Web.Http; namespace WebApiWebFormHost { public class

KeyMob广告聚合API服务

现如今,KeyMob广告聚合API服务是为发者又多了一种一站式解决方案新选择,现在只需将KeyMob SDK嵌入自身的应用代码,即可集成数家广告平台,无需再单独安装广告平台SDK. 当前广告聚合服务的实现,依赖于开发者在应用内嵌入选定的广告平台SDK之后,再加入广告聚合SDK,来完成广告管理和优化功能.这种方式往往会导致应用体积增大,并且由于代码元素的复杂性,给开发者平添许多工作量. 而API接入的方式则可以很好地避免这些窘境,KeyMob广告聚合API使开发者仅通过果合SDK就可以实现所有功能