简体   繁体   English

Angular指令$ http。 http响应之前和之后

[英]Angular directive $http. Before and after http response

Simple things.. 简单的事情..

<my-directive info-key="total_users"></my-directive>

Result: <div>You asked for {{ infoKey }}, you get {{ apiValue }}</div> 结果: <div>You asked for {{ infoKey }}, you get {{ apiValue }}</div>

Now the thing is that before the API respond I want to add some html there. 现在问题是在API响应之前我想在那里添加一些html。

Eg <div You asked for {{ infoKey }}, you get <small>pending..</small></div> and then remove it for the API result. 例如<div You asked for {{ infoKey }}, you get <small>pending..</small></div> ,然后将其删除以获得API结果。

Of course I tried to initialise the result $scope.apiValue = 'pending...'; 当然我试图初始化结果$scope.apiValue = 'pending...'; but I was just wondering if there is a better way because I'm not so familiar with "the Angular way" yet. 但我只是想知道是否有更好的方法,因为我还不熟悉“Angular方式”。

I even though that maybe my whole logic is false so please check the code snippet below. 我即使这可能是我的整个逻辑都是假的,所以请检查下面的代码片段。

 apiUrl = 'https://api.stackexchange.com/2.2/info?site=stackoverflow'; angular.module('app', []).directive('myDirective', [ function() { return { restrict: 'E', replace: true, template: '<div>you asked for <strong>{{ infoKey }}</strong>, you get: <strong>{{ apiValue }}</strong></div>', controller: ['$scope', '$http', function($scope, $http) { $scope.askApi = function(key) { $http.get(apiUrl).success(function(data) { $scope.apiValue = data.items[0][key]; }); }; } ], link: function(scope, element, attrs, ctrl) { scope.infoKey = attrs.infoKey; scope.askApi(scope.infoKey); } } } ]); 
 <html ng-app="app"> <head></head> <body> <my-directive info-key="total_users"></my-directive> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> </body> </html> 

You're generally on the right track. 你通常走在正确的轨道上。 However, as you've noticed you don't follow the best angular practices. 但是,正如您已经注意到的那样,您没有遵循最佳角度练习。 A few things that I would change (shown below): 我会改变一些事情(如下所示):

  1. Avoid using $scope and instead use controllerAs syntax. 避免使用$ scope而是使用controllerAs语法。 Avoiding $scope gets rid of a whole lot of errors and confusion that can happen due to the prototypical inheritance and sharing that $scopes have. 避免$ scope消除了由于原型继承和$ scope的共享而可能发生的大量错误和混乱。

  2. Don't use replace, instead use the element as your containing element. 不要使用replace,而是使用元素作为包含元素。 It is functionally equivalent and makes your markup more semantic. 它在功能上是等效的,使您的标记更具语义性。 The only thing to bare in mind here is that custom elements will have a display: inline; 这里唯一要记住的是自定义元素将有一个显示:inline; style by default rather than display: block; 默认情况下的样式而不是display:block; that it would have if it was a div. 如果它是一个div它会有。

  3. Use bindToController. 使用bindToController。 To be fair this came in with angular 1.3 and your example used angular 1.2. 公平地说,这是角度1.3,你的例子使用角度1.2。 Suffice to say it removes some of the code. 我只想说它删除了一些代码。

  4. Separate your API access logic into a service. 将API访问逻辑分离为服务。

And here are another few things I would add that I haven't shown: 以下是我要添加的另外几件我没有展示的内容:

  1. Tests! 测试! Angular is set up to make unittesting easy. Angular的设置使单元测试变得容易。 Your understanding of the code will improve massively by writing tests, not to mention the other benefits you get from writing them. 通过编写测试,您对代码的理解将大大提高,更不用说编写代码所带来的其他好处。

  2. Handle errors. 处理错误。 After the .success() of the promise in the controller you should have a .catch() block and handle an error. 在控制器中的promise的.success()之后,您应该有一个.catch()块并处理错误。 Even just presenting an error to the user would be of benefit, or even including a retry button. 即使只是向用户呈现错误也是有益的,甚至包括重试按钮。

 angular.module('app', []).directive('myDirective', [ function() { return { restrict: 'E', template: 'you asked for <strong>{{ vm.infoKey }}</strong>, you get: <strong>{{ vm.apiValue }}</strong>', controllerAs: 'vm', scope: { infoKey: '@' }, bindToController: true, controller: ['stackoverflowInfo', function(stackoverflowInfo) { var vm = this; vm.apiValue = 'pending ...'; stackoverflowInfo.get(vm.infoKey).then(function(value) { vm.apiValue = value; }); } ] } } ]).service('stackoverflowInfo', ['$http', '$q', function ($http, $q) { var svc = this; var apiUrl = 'https://api.stackexchange.com/2.2/info?site=stackoverflow'; svc.get = get; function get (key) { return getFromApi().then(function(data) { return data.items[0][key]; }); } function getFromApi () { var defer = $q.defer(); $http.get(apiUrl).success(defer.resolve).error(defer.reject); return defer.promise; } }]); 
 <html ng-app="app"> <head></head> <body> <my-directive info-key="total_users"></my-directive> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script> </body> </html> 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM