聚合数据api连接app_将API驱动的Web App与Javascript连接

本文介绍如何使用JavaScript连接API,创建交互式Web应用。通过实际案例,讲解了如何处理表单提交,验证用户输入,显示加载状态,处理API请求及响应,最终在页面上呈现结果。

聚合数据api连接app

我们的小应用程序只是按照我们想要的方式显示,但实际上并没有做任何事情。 因此,让我们添加一些JavaScript来使应用程序具有交互性。

本系列的这一部分将需要您的专心,但是即使您不是经验丰富JavaScript开发人员,我也要保证您会学到一些有价值的技能,然后离开。

最初设定

首先,我们将创建我们的javascript文件assets/js/main.js并在其中创建一个名为Gimmie的对象(以我们的应用程序命名)。 在这里我们将存储所需的变量和函数,以使它们不在window对象上。 我们将它放在我们还将使用的jQuery的“ document ready”调用旁边。

var Gimmie = {
    $content: $('.content'),
    $form: $('form'),
};

$(document).ready(function(){
    // On page load, execute this...
});

注意,我们在Gimmie对象中添加了一些变量: $content$form 。 这些是jQuery对象,因此我们在它们前面加一个$来提醒我们这一点。 由于它们是特定的DOM节点,因此我们将多次引用它们,将它们存储在变量中以备将来使用。

表格提交

我们需要处理的第一件事是用户在表单中输入内容并提交时。 因此,在“文档准备就绪”内部,我们将在表单上附加一个侦听器事件。 我们可以执行$('form').on()但是由于我们已经将form元素存储在变量中,因此我们将通过Gimmie.$form.on()引用它。 然后,我们将阻止默认的表单操作(因此页面不会刷新):

$(document).ready(function(){
    Gimmie.$form.on('submit', function(e){
        e.preventDefault();
        // Do more stuff here...
    });
});

载入中

现在,我们要在用户提交表单时显示“正在加载”状态。 这样,他们就知道发生了什么事。 如果您还记得,我们是在Sketch中设计的:

为此,我们将在Gimmie对象内创建一个名为toggleLoading的函数,当用户提交表单时,可以通过在表单提交侦听器内调用Gimmie.toggleLoading()来执行该函数。 我们将其命名为toggleLoading是因为我们将在UI中切换当前的加载状态,即在提交时执行一次,然后运行一堆代码,完成后将再次运行它以消除加载州。

var Gimmie = {
    /* our other code here */

    toggleLoading: function(){
        // Toggle loading indicator
        this.$content.toggleClass('content--loading');
        
        // Toggle the submit button so we don't get double submissions
        // https://stackoverflow.com/questions/4702000/toggle-input-disabled-attribute-using-jquery
        this.$form.find('button').prop('disabled', function(i, v) { return !v; });
    },
}
$(document).ready(function(){
    Gimmie.$form.on('submit', function(e){
        e.preventDefault();
        Gimmie.toggleLoading(); // call the loading function
    });
});

请注意,我们正在.content元素上切换一个名为content--loading 。 我们需要围绕它创建一些CSS样式。 因此,在我们CSS文件中,我们添加:

.content--loading:before {
    content: '';
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background: #fff;
    opacity: .9;
    z-index: 10;
}

.content--loading:after {
    content: url('../img/loading.gif');
    position: absolute;
    left: 50%;
    top: 3em;
    margin-left: -16px;
    margin-top: -16px;
    z-index: 11;
}

在这里,我们使用伪元素在内容区域上创建加载状态。 我们的before元素用于在内容区域上创建稍微不透明的白色叠加层。 然后,我们使用after元素在框内显示动画加载gif。 当此类添加到我们的内容部分时,它将看起来好像正在加载某些东西。

此时,如果您在输入字段中输入任何内容并提交表单,则将显示加载状态,您将只能停留在该状态。

表格验证

在向iTunes API提交请求之前,请确保用户输入的数据正确。

那么,什么才是正确的数据呢? 好吧,如果我们查看iTunes API文档 ,则有几种获取内容的不同方法。 一种方法是根据关键术语进行搜索。 但是我们要做的是称为“查找”。 从文档:

您还可以创建查找请求,以根据iTunes ID在商店中搜索内容

然后提供了一些示例,例如通过其iTunes ID查找Yelp软件应用程序: https://itunes.apple.com/lookup?id=284910350 : https://itunes.apple.com/lookup?id=284910350 id https://itunes.apple.com/lookup?id=284910350 。 请注意,应用程序的ID号是这些URL之间共享的。 这就是我们需要用户的东西。

从UX的角度来看,在应用商店中为应用寻找标识符可能会有些困难(尤其是对于新手)。 因此,我们不要求人们如何获取应用程序ID,而是要求提供应用程序的商店链接。 每个人都知道如何复制和粘贴链接! 只需从应用程序商店(在iTunes,网络或Mac App Store中)的单个应用程序页面复制链接,任何人都可以轻松获得应用程序链接。

因此,一旦用户输入链接,我们就需要对其进行验证:

  1. 确保它是一个以http://itunes开头的有效网址
  2. 确保它包含一个ID

为此,我们将在Gimmie变量内创建一个validate函数,并在表单提交事件侦听器上执行它。

var Gimmie = {
    /* our prior code here */
    userInput: '',
    userInputIsValid: false,
    appId: '',
    validate: function(input) {
        // validation happens here
    },
}

Gimmie.$form.on('submit', function(e){
    /* our previous code here */
    Gimmie.userInput = $(this).find('input').val();
    Gimmie.validate();
    if( Gimmie.userInputIsValid ) {
        /* make API request */
    } else {
        /* throw an error */
    }
});

注意我们在上面的代码中正在做什么:

  • 我们为Gimmie添加了一些变量和一个函数
    • userInput是一个字符串,并设置为来自用户的输入
    • userInputIsValid是一个布尔值,根据用户输入是否有效,该布尔值将为true或false(我们稍后将编写这些测试)
    • appId是一串数字,如果有效则将从userInput提取
    • validate是一个函数,在调用该函数时,我们将验证用户的输入
  • 在提交表单时,我们:
    • Gimmie.userInput设置为表单输入字段的值
    • Gimmie.validate()执行验证功能
    • 运行if / else语句。 如果用户输入有效(由我们的Gimmie.validate决定),那么我们将继续进行并发出iTunes API请求。 如果无效,我们将显示错误消息,通知用户他们输入的数据不正确。

现在,让我们编写验证用户输入是否正确的代码。 请注意,在HTML中,我们将输入类型设置为url <input type="url"> 。 这意味着某些浏览器将在本地对输入执行某种类型的验证,但是在不同的浏览器中不一致或不一致。 在某些浏览器中,它甚至无法工作。 因此,如果用户键入“ blah”,浏览器将接受它并提交表单。 在其他浏览器中,他们至少必须键入以“ http://”开头的内容,然后浏览器才允许他们提交表单。 但是我们想要的是一个以“ http:// itunes”开头的URL,因此我们将使用JavaScript进行处理。

var Gimmie = {
    /* our prior code */
    validate: function() {
        // Use regex to test if input is valid. It's valid if:
        // 1. It begins with 'http://itunes'
        // 2. It has '/id' followed by digits in the string somewhere
        var regUrl = /^(http|https):\/\/itunes/;
        var regId = /\/id(\d+)/i;
        if ( regUrl.test(this.userInput) && regId.test(this.userInput) ) {
            this.userInputIsValid = true;
            var id = regId.exec(this.userInput);
            this.appId = id[1];
        } else {
            this.userInputIsValid = false;
            this.appId = '';
        }
    }
}

在这里,我们使用正则表达式来测试输入是否满足我们的条件。 让我们更详细地介绍一下:

var regUrl = /^(http|https):\/\/itunes/i;
var regId = /\/id(\d+)/i;

这是我们定义的两个正则表达式文字( 更多有关正则表达式的信息 )。 这是这些正则表达式的简要说明:

  • regUrl是用于确定用户输入是否为以“ http:// itunes”开头的URL的正则表达式文字。
    • /^表示“启动正则表达式并开始查看字符串的开头”
    • (http|https):说“寻找'http'或'https',后跟分号':'”
    • \/\/表示“查找'//'”(因为正斜杠在正则表达式中是一个特殊字符,就像我们在正则表达式开始处使用它的方式一样,我们必须在正斜杠之前使用反斜杠告诉正则表达式不要将正斜杠解释为特殊字符,而只能解释为正斜杠)
    • itunes/i说“寻找'itunes'然后结束正则表达式”,而末尾的i表示匹配应该不区分大小写(因为有人可能会粘贴仍然有效的“ HTTP:// ITUNES”)
  • regId是用于确定用户输入是否具有与iTunes商店链接URL模式匹配的数字的ID的正则表达式文字。 所有有效的iTunes store链接都将包含/id ,后跟数字序列。
    • /\/id表示“启动正则表达式,并在字符串中的任何地方查找'/ id'”(有关斜杠转义的描述,请参见前面的示例)
    • (\d+)表示“寻找1次或多次的数字序列(0至9)并捕获它们”。 括号表示我们想记住内部定义的任何匹配项,即在我们的情况下,我们记住代表应用程序ID的数字序列。 /d是正则表达式中的特殊字符,表示我们希望数字[0-9],而+表示匹配那些[0-9] 1次或更多次。
    • /i说“结束正则表达式”,并且i表示不区分大小写的匹配(因为带有/ID938491的URL仍然有效)

我们的代码的下一部分如下所示:

if ( regUrl.test(this.userInput) && regId.test(this.userInput) ) {
    this.userInputIsValid = true;
    var id = regId.exec(this.userInput);
    this.appId = id[1];
} else {
    this.userInputIsValid = false;
    this.appId = '';
}

正则表达式文字上的.test()方法从指定的字符串中查找匹配项,并根据找到的指定匹配项返回true或false。 因此,在我们的示例中,我们针对regUrlregID来测试用户的输入,以确保输入均以“ http:// itunes”开头,并以“ / id”开头,后跟许多数字。

如果两个测试都返回true,则将userInputIsValid标志设置为true,然后从URL中提取ID并将其设置为appId 。 为此,我们在输入上运行.exec()方法。 这将返回一个包含两个项目的数组:一个与整个正则表达式匹配,另一个仅与/id之后的数字字符串匹配(这是因为我们使用了正则表达式(/d+)的括号来表示“记住在这里捕获的内容”) )。 因此,作为示例, .exec()方法将返回类似["/id12345", "12345"]而我们只需要数组中的第二项,因此我们将appId设置为该值。

如果两个测试均返回false,则将userInputIsValid设置为false,并将appId设置为空字符串。

现在,我们需要确定用户输入是否有效的所有内容。 因此,我们可以继续执行脚本的其余部分。

投掷错误

现在,在脚本中,我们可以确定用户的输入是否是我们需要的。 因此,我们离开了:

if( Gimmie.userInputIsValid ) {
    /* make API request */
} else {
    /* throw an error */
}

目前,我们将处理“引发错误”部分。 因为在执行脚本的过程中还会有其他可能发生错误的地方,所以我们将制作一个通用的错误函数,该函数将根据错误的内容向用户显示错误。 如果您还记得,我们设计了Sketch中的外观:

请注意,我们的错误状态实际上具有两项:一个是粗体文本的“标题”,另一个是常规设置文本的“正文”。 因此,我们将创建一个接受这些错误的通用错误函数。 “标题”通常会说明错误,“正文”将说明如何解决错误。 因此,在这种特殊情况下,如果来自用户的输入无效,我们需要告知他们正确的输入类型是什么。 因此,让我们创建一个通用函数,该函数可以根据传递给它的文本显示错误:

if( Gimmie.userInputIsValid ) {
    /* make API request */
} else {
    Gimmie.throwError(
        'Invalid Link',
        'You must submit a standard iTunes store link with an ID, i.e.
https://itunes.apple.com/us/app/twitter/ id333903271 ?mt=8 ' ); }

在这里,我们调用函数Gimmie.throwError()并向其传递两个参数:“标题”文本和“正文”文本。 因为我们只是显示HTML,所以我们可以根据需要在参数内传递HTML元素。 在这种情况下,我们在“正文”中传递了一个示例iTunes Store链接,并突出显示了带有重点标签( <em> )的id/部分,以帮助向用户指示“嘿,我们需要一个iTunes store链接,并确保其中有一个ID”。

我们可以设置CSS以突出显示<em>标记中包装的内容,并为错误状态赋予颜色:

.content--error {
    color: #196E76;
}
.content em {
    font-style: normal;
    background-color: lightyellow;
}

现在,我们将在Gimmie对象中创建throwError函数:

var Gimmie = {
    /* prior code here */
    throwError: function(header, text){
        this.$content
            .html('

' + header + ' ' + text + '

') .addClass('content--error'); this.toggleLoading(); } }

注意,我们正在抓取this.$content 。 这与执行$('.content')但是我们将所选$('.content')保存为Gimmie对象中的变量,因为我们将多次使用它。 因此,我们通过执行this.$content引用它。 现在,我们将$content元素HTML内容设置为传入的文本,“标题”文本为粗体。 然后,我们在内容元素中添加一类content--error这样,我们便可以按需要设置错误的样式。 最后,我们运行toggleLoading()的函数Gimmie删除加载类,并停止显示加载GIF。

此时,如果您输入了错误的URL(例如http://google.com ,或者输入了没有ID(例如https://itunes.apple.com/us/app/twitter/的正确的iTunes URl, https://itunes.apple.com/us/app/twitter/您应该看到显示的错误消息:

为了稍微增强我们的形式,让我们添加一个不错的小“ pop”动画,该动画在发生错误时运行(在受支持的浏览器中)。 为此,我们将添加/删除一个包含动画CSS类。 因此,在我们CSS文件中,执行以下操作:

.content--error-pop {
    -webkit-animation: pop .333s;
    -moz-animation: pop .333s;
    -o-animation: pop .333s;
    animation: pop .333s;
}

@-webkit-keyframes pop {
    0%   {-webkit-transform: scale(1);}
    50%  {-webkit-transform: scale(1.075);}
    100% {-webkit-transform: scale(1);}
}

@-moz-keyframes pop {
    0%   {-webkit-transform: scale(1);}
    50%  {-webkit-transform: scale(1.075);}
    100% {-webkit-transform: scale(1);}
}

@-o-keyframes pop {
    0%   {-webkit-transform: scale(1);}
    50%  {-webkit-transform: scale(1.075);}
    100% {-webkit-transform: scale(1);}
}

@keyframes pop {
    0%   {-webkit-transform: scale(1);}
    50%  {-webkit-transform: scale(1.075);}
    100% {-webkit-transform: scale(1);}
}

这将使内容区域在大小上进行缩放,并在发生错误时使其“弹出”。 现在,我们只需要使用JavaScript添加/删除该类。 回到我们的throwError函数:

throwError: function(header, text){
        // Remove animation class
        this.$content.removeClass('content--error-pop');

        // Trigger reflow
        // https://css-tricks.com/restart-css-animation/
        this.$content[0].offsetWidth = this.$content[0].offsetWidth;

        // Add classes and content
        this.$content
            .html('

' + header + ' ' + text + '

') .addClass('content--error content--error-pop'); this.toggleLoading(); },

在这里,我们先删除该类,然后触发“重排”以确保在下一步添加该类时(连同常规的content--error类)动画再次开始。 现在,我们在错误状态上还有一个不错的弹出动画:

发出API请求

我们现在快要完成了。 我们已经检查以确保来自用户的输入是正确的,并且我们提供了一种显示错误的方法,因此现在我们只需要发出API请求即可。

我们将在验证用户输入的if()语句中进行此操作。

if( Gimmie.userInputIsValid ) {
    $.ajax({
        url: "https://itunes.apple.com/lookup?id=" + Gimmie.appId,
        dataType: 'JSONP'
    })
    .done(function(response) {
        // when finished
    })
    .fail(function(data) {
        // when request fails
    });
} else {
    /* our other code here */
}

从上面的代码中可以看到,我们已经设置了对iTunes APIAJAX请求 。 您可能还记得,iTunes API有一个“查找” URL,我们可以点击它来获取数据。 它遵循以下格式: https://itunes.apple.com/lookup?id= : https://itunes.apple.com/lookup?id= id https://itunes.apple.com/lookup?id=后跟您要查找的事物的ID。 该API提供了使用Yelp应用程序查找软件应用程序的示例: https ://itunes.apple.com/lookup ? id = 284910350。 如果在浏览器中转到该URL,则会看到一堆JSON:

如果您通过lint之类的linter进行运行,结果将被格式化并开始变得更有意义:

如果查看API文档,您会注意到API为iTunes商店中的所有内容提供了结果,从音乐到电影再到应用程序。 这对我们是有利的,因为这意味着我们不仅可以获取iOS应用程序的图标作品,还可以获取Mac应用程序的图标作品! Mac应用程序使用与iOS应用程序相同类型的URL结构。 例如,Final Cut Pro的链接为https://itunes.apple.com/us/app/final-cut-pro/id424389933?mt=12 。 请注意,URL以https://itunes开头并带有/id424389933 ,这正是我们所需要的!

使用前面的错误函数,让我们针对如果/当我们的API请求失败时抛出错误:

if( Gimmie.userInputIsValid ) {
    $.ajax({
        url: "https://itunes.apple.com/lookup?id=" + Gimmie.appId,
        dataType: 'JSONP'
    })
    .done(function(response) {
        // when finished
    })
    .fail(function(data) {
        Gimmie.throwError(
            'iTunes API Error',
            'There was an error retrieving the info. Check the iTunes URL or try again later.'
        );
    });
} else {
    /* our other code here */
}

当我们将显示错误的方法抽象为一个函数时,显示另一个错误很容易!

响应

现在让我们担心请求成功完成时会发生什么:

$.ajax({
    /* other code here */
})
.done(function(response) {
    // Get the first response and log it
    var response = response.results[0];
    console.log(response);
})
.fail(function(data) {
    /* other code here */
});

请注意,这里我们正在获取响应并将第一个结果记录到控制台。 如果看一个示例API请求,您会看到在JSON对象的最顶层,您将得到resultCount ,它告诉您有多少个结果(在查找中应该只有一个),然后results是表示结果的数组(在这种情况下,只有一个对象)。

因此,我们将响应设置为结果中的第一项,然后将其记录到控制台。 如果您在浏览器中打开我们的小应用程序并输入URL(例如,Yelp URL https://itunes.apple.com/lookup?id=284910350 ),您将看到UI停留在加载状态,但是如果您查看开发工具并转到控制台,则会看到记录了我们的API响应。 现在,我们可以在JavaScript中访问任何这些属性!

如您所见,API返回了有关该应用程序的大量信息:其名称,开发人员,描述,类型,价格等! 我们真的只需要其中的一些东西,例如应用程序的图标。 因此,我们将进行检查以确保我们的请求中包含我们所需的信息。

$.ajax({
    /* other code here */
})
.done(function(response) {
    // Get the first response and log it
    var response = response.results[0];
    console.log(response);

    // Check to see if request is valid & contains the info we want
    // If it does, render it. Otherwise throw an error
    if(response && response.artworkUrl512 != null){
        Gimmie.render(response);
    } else {
        Gimmie.throwError(
            'Invalid Response',
            'The request you made appears to not have an associated icon.
Try a different URL.' ); } }) .fail(function(data) { /* other code here */ });

在这里,我们检查以确保response存在,并检查以确保response.artworkUrl512是该响应的一部分。 artworkUrl512是API提供的指向完整尺寸应用程序图标的链接的密钥。 如果存在这些内容,我们将在页面上显示应用程序图标。 为此,我们还有另一个称为render函数,我们将在稍后编写。 如果由于某种原因缺少了我们需要的东西,我们会用已经完成的漂亮函数抛出另一个错误。

渲染API结果

现在我们有了API返回所需的数据,现在让我们在页面上呈现结果。 一旦知道我们拥有API所需的一切,就调用Gimmie.render(response)并将API响应传递给它,它只是键/值对的一个对象。 因此,回到我们的Gimmie对象,让我们创建render函数:

var Gimmie = {
    /* our other code here */
    render: function(response){
        var icon = new Image();
        icon.src = response.artworkUrl512;
        icon.onload = function() {
            Gimmie.$content
                .html(this)
                .append('

' + response.trackName + '

') .removeClass('content--error'); Gimmie.toggleLoading(); } } }

这是我们在这段代码中所做的:

  • 要从头开始创建图像,我们创建一个名为icon的变量,并使用Image()构造函数,该构造函数基本上创建一个HTMLImageElement 。 可以将其想象为使用JavaScript在内存中创建<img>标签。
  • 然后,由于使用了Image()构造函数,因此可以使用可用的icon.src方法来设置图像的src属性。 我们将图像的来源设置为响应的artworkUrl512 。 这将使浏览器开始在指定的URL处获取图像。
  • 我们使用icon.onload告诉浏览器“完成图像获取后,执行此操作……”。 这是一种让浏览器获取图像资源,然后才将其下载到DOM中的方法。
  • icon.onload内,我们将$contentsHTML设置为刚检索的图像。 然后,如果需要,我们可以将更多信息附加到该内容区域。 在此示例中,我从API响应中获取trackName ,以显示应用程序的名称及其图标。
  • 最后执行我们的toggleLoading函数,因为我们已经完成了所有内容的加载!

立即尝试在浏览器中运行它,您应该会看到一个漂亮的图标! 例如,尝试使用Yelp URL https://itunes.apple.com/us/app/yelp/id284910350?mt=8

尝试使用Mac应用程序URL,例如Final Cut Pro https://itunes.apple.com/us/app/final-cut-pro/id424389933?mt=12

加载图标蒙版

请注意,iOS图标未四舍五入。 如前所述,大多数iOS图标未设计为带有圆角。 这些应用在操作系统级别。 对于iOS图标,我们将必须应用在Sketch中创建的蒙版。 因此,如果进入Sketch并导出我们作为图像资源创建的蒙版,则在加载图标时会将其加载到浏览器中:

var Gimmie = {
    render: function(response){
        var icon = new Image();
        icon.src = response.artworkUrl512;
        icon.onload = function() {
            Gimmie.$content
                .html(this)
                .append('

' + response.trackName + ' Actual icon dimensions: ' + this.naturalWidth + '×' + this.naturalHeight + '

') .removeClass('content--error'); Gimmie.toggleLoading(); // If it's an iOS icon, load the mask too if(response.kind != 'mac-software') { var mask = new Image(); mask.src = 'assets/img/icon-mask.png'; mask.onload = function() { Gimmie.$content.prepend(this); } } } } }

这是我们正在做的:

  • 在我们的API结果中,有一个称为“种类”的对象,该对象是指API返回的事物的种类,例如电影,音乐或软件。 Mac应用程序将具有“种类”的“ mac-software”。 由于Mac应用程序不需要在其图标上应用遮罩,因此我们检查响应类型是否不是“ mac-software”。 如果不是,我们就知道它是一个iOS应用,然后我们就可以加载遮罩了
  • 我们使用与以前相同的Image()构造函数,将图像的src设置为保存蒙版的位置,然后在为图像触发onload事件之后将其添加到内容区域。

现在,我们只需要添加一些样式即可在图标上放置遮罩:

.content img[src*="icon-mask.png"] {
    position: absolute;
    left: 0;
    top: 0;
}

而已! 如果您再次输入Yelp URL,这次它将以圆角显示!

完成!

这是一段漫长的旅程,希望您从本教程中学到了很多东西! 我们介绍了为我们的应用及其不同状态创建线框和模拟。 我们还介绍了为与第三方API接口的Web应用程序编写HTML,CSS和Javascript。

希望您已经掌握了与API接口的一些基础知识。 您已经了解了如何从API动态提取内容和资产并将其全部呈现到网页中。 有了这些基本知识,您现在可以着手创建更多针对您的兴趣的个性化Web应用程序。

以下是一些API的列表:

翻译自: https://webdesign.tutsplus.com/tutorials/connecting-an-api-driven-web-app-with-javascript--cms-24576

聚合数据api连接app

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值