注意: 本文由Siyuan Hua于2016.01.17更新。
- 用
ng-model-option
反跳功能和$watch
服务替换了不必要的setTimeout
和clearTimeout
调用。 -
.success()
/.error()
已过时,已更新为使用.then(success_callback, error_callback)
代替。 - 修复损坏的海报图像。
如今,Web应用程序通过API相互通信是司空见惯的。 例如,当您在线购买电影票时,电影票网站使用远程API来验证您的信用卡信息是否正确。 在本教程中,我将研究如何使用AngularJS向远程API发出HTTP请求,以及如何处理API的JSON响应,以便更新视图。
保持电影主题不变 ,我将通过构建一个名为Fastr的电影浏览器来演示这一点 ,该浏览器将获取有关您想要输入的任何电影的各种不同信息。 除了AngularJS之外 ,还将使用Bootstrap进行样式设置以及使用Animate.css进行一些时髦效果构建Fastr 。
这就是我们的最终结果:
该项目的代码可从我们的GitHub存储库中获得 ,或者您可以在CodePen上查看有效的演示 。
项目结构
我们将代码保持在模块化结构中,如下所示:
css/
animate.min.css
bootstrap.min.css
style.css
js/
angular.min.js
app.js
partials/
main-info.html
related-results.html
index.html
文件index.html将包含我们应用程序的主视图。 其中大部分是样板,但让我们检查一下操作在哪里发生:
<div class="input-group search-bar">
<input type="text"
ng-model="search"
ng-model-options="{ debounce: 800 }"
placeholder="Enter full movie name" />
...
</div>
<div id="main-info"
ng-include="'partials/main-info.html'">
</div>
<div id="related-results"
ng-include="'partials/related-results.html'">
</div>
如您所见,我们已经使用ng-model
将输入字段(用户将在其中输入电影名称)绑定到search
模型(我们将在控制器中声明)。 我们还使用了debounce
值为800的ng-model-options
指令,以确保至少以800ms的延迟更新模型。 我们还将使用$watch
服务监视搜索模型中的更改,并注册一个回调以在每次检测到更改时获取数据。 您将在以下部分中看到这一点。
main-info
和related-results
div将分别用于显示有关当前电影的信息和相关电影的列表。 信息将显示为ng-include
指令获取,编译和包含的部分内容。
调用数据API
让我们看一下app.js ,它是应用程序的核心。 我们首先将$scope
和$http
作为参数传递给控制器的构造函数。 这意味着我们正在声明对范围对象和http服务的依赖。
.controller('MovieController', function($scope, $http){
现在,当页面第一次加载时,搜索模型是未定义的。 因此,我们将其设置为“ Sherlock Holmes”并调用fetch
函数,该函数将联系远程API并确保视图已初始化。
现在,在MovieController
,我们设置了对search
模型的监视,并在搜索框中的字符串更改时加载结果。 我们想要的是,仅应在用户停止键入800毫秒后才获取结果(请记住,我们使用的ngModelOptions
伪指令的debounce
值为800)。 这样可以防止应用程序对API进行不必要的调用。 我们还希望在输入时立即看到结果(我们不想按Enter或单击任何搜索按钮)。
$scope.$watch('search', function() {
fetch();
});
现在,我们定义change
功能。 当搜索框中的字符串更改时,它将加载结果。 我们想要的是,仅在用户停止键入800毫秒后才应获取结果。 这样可以防止应用程序向API发送不必要的调用。 我们还希望在输入时立即看到结果(我们不想按Enter或单击任何搜索按钮)。
然后,我们在控制器中将search
模型初始化为“ Sherlock Holmes”,进而调用在$watch
服务中注册的fetch()
回调,该回调与远程API联系并确保初始化视图。
$scope.search = "Sherlock Holmes";
接下来是fetch
功能。 此函数调用API并处理作为响应发送的JSON数据。 我们将用于电影浏览器的API是OMDb API,这是一种免费的Web服务,用于获取电影信息。 如果您对API的工作方式感到好奇,建议您在上面的链接中查看全面的文档。
为了发出请求,我们使用Angular的$http.get
函数,将API URL和串联的查询字符串作为参数传递给它。 发出了两个对不同URL的请求-第一个请求检索有关电影的主要信息,第二个请求检索相关结果。
成功后,我们将响应分别存储在一个称为details
的模型和一个称为“ related
的模型中。
function fetch(){
$http.get("http://www.omdbapi.com/?t=" + $scope.search + "&tomatoes=true&plot=full")
.then(function(response){ $scope.details = response.data; });
$http.get("http://www.omdbapi.com/?s=" + $scope.search)
.then(function(response){ $scope.related = response.data; });
}
接下来是update
功能。 当用户单击视图中的相关标题之一时,将调用此方法。 它接受一个对象(包含有关电影的信息),并将我们的Search
模型设置为该电影标题的值。 当$watch
模型更改时, $watch
服务仍然可以执行魔术操作以提取有关该电影的信息。
$scope.update = function(movie){
$scope.search = movie.Title;
};
最后,我们有一个便捷功能select
,可确保当用户单击文本输入时选择整个文本。
$scope.select = function(){
this.setSelectionRange(0, this.value.length);
}
处理回应
现在让我们分析partials / main-info.html文件。
如果列表尚未加载,我们首先使用ng-if
指令显示消息“ Loading Results… ”,然后检查details.Response==='True'
以查看API是否在找到匹配项时请求退货。
在返回结果的情况下,我们使用ng-src
指令检查details.Poster
的内容并加载包含引用的图像,或者如果没有可用的图像则加载占位符图像。
<img ng-src="{{ details.Poster=='N/A' ?
'http://placehold.it/150x220&text=N/A' :
details.Poster }}">
之后,我们使用Angular的数据绑定来显示剩余的电影详细信息,然后在页面底部包括四个到外部站点的链接,用户可以在该站点上获取有关电影的更多信息。 我们使用ng-href
指令来呈现这些链接,就像我们在href
属性中使用Angular表达式一样 ,如果用户在Angular有机会用其值替换该表达式之前单击链接,那么事情将会中断。
最后,让我们检查partials / related-results.html
<div ng-if="related.Response!=='False'">
Related Results:<hr>
<ul class="rel-results">
<li ng-repeat="movie in related.Search">
<a href="#" id="{{ $index + 1 }}"
ng-click="update(movie)">{{ movie.Title }}
</a>, {{ movie.Year }}
</li>
</ul>
</div>
同样,我们在渲染任何东西之前使用ng-if
检查响应。 然后,我们使用ng-repeat
指令遍历related
模型的Search
属性,该属性包含(除其他事项外)与正在搜索的电影相关的电影标题列表。
每当单击标题时,我们还使用ng-click
调用控制器的更新功能。 如上所述,更新功能将确保获取并显示此新电影的信息。
最后的修饰
我们可以在index.html
添加一些noscript
标记,以便在禁用或不支持用户浏览器的JavaScript时显示错误消息。 我们还可以包含animate.css
来添加一些很酷的动画,例如翻转海报图像,放大内容并弹出相关结果。 使用animate.css
就像在元素的类中指定动画的名称一样简单,在字符串animation
之前。 例如:
<div class="animated zoomInRight">
结果就是这里!
请注意,由于空间限制,我已将相关结果隐藏在嵌入式演示中。 要查看它们,只需在CodePen上查看演示(无论如何,这是个好主意,因为那里的演示速度更快)。
请参阅CodePen上的SitePoint( @SitePoint )提供的笔YXXQxj 。
结论
在本教程中,我演示了如何使用AngularJS向远程API发出请求,以及如何使用Angular的数据绑定机制立即用结果更新视图。 构建这样的项目可能是学习特定语言或框架功能的好方法,因此,我建议您克隆存储库并进一步改进应用程序。
From: https://www.sitepoint.com/api-calls-angularjs-http-service/