Coffeescript中的以下虚拟控制器:
GlobalTimelineController = ($scope, $http) ->
$http.get('/api/globalTimeline').success (posts) ->
$scope.posts = posts
按如下方式编译为Javascript:
(function() {
var GlobalTimelineController;
GlobalTimelineController = function($scope, $http) {
return $http.get('/api/globalTimeline').success(function(posts) {
return $scope.posts = posts;
});
};
}).call(this);
我想知道Coffee编译器添加的这些 return 语句的副作用是什么?正确性和性能都明智吗?
我应该关心这个并且在我的方法和回调结束时返回空白吗?
答案 0 :(得分:1)
$ http.get调用返回一个所谓的“promise”,其工作方式如下:
promise.success = function(fn) {
promise.then(function(response) {
fn(response.data, response.status, response.headers, config);
});
return promise;
};
取自AngularJS源代码(/src/ng/http.js:700)
这意味着无论你的函数返回什么都被忽略,所以如果它是object,那么在你的函数完成后它的引用就会丢失。 因此,从正确的角度来看,它并不重要。
现在,如果我们看一下表现,在这种情况下,差异(如果有的话)可以忽略不计。 但是,您始终需要牢记这一行为。如果您在函数中执行的最后一件事是执行一些具有多次迭代的循环,则coffeescript将返回一个由每个数组迭代的结果组成的大数组(数组理解)。它不仅会影响性能,而且在极端情况下可能会导致JS内存不足!
您还可以在末尾附加一个return语句,以防止coffeescript生成此类数组。
答案 1 :(得分:1)
前一段时间处理的唯一问题与单元测试控制器方法有关。
beforeEach inject ($injector)->
$controller = $injector.get '$controller'
injectables = { ... }
ctrl = $controller 'app.controllers.FooBarCtrl', injectables
describe 'Controller ...', ->
it 'should have foo property', ->
expect(ctrl.foo).toBeDefined()
name = 'app.controllers.FooBarCtrl'
angular.module(name, []).controller(name, [
'$scope'
'$http'
($scope)->
scope.foo = 'bar'
$http.get '/foo/bar', (res)-> console.log 'response: ', res
])
在这种情况下,您将无法测试任何控制器方法,因为返回的内容实际上是一个承诺。为了获得对实际控制器方法的访问,您需要返回它,如下所示:
name = 'app.controllers.FooBarCtrl'
angular.module(name, []).controller(name, [
'$scope'
'$http'
($scope)->
scope.foo = 'bar'
$http.get '/foo/bar', (res)-> console.log 'response: ', res
@ # <--- look ma, I'm here!
])
但是,从实际的角度来看,我认为这些示例并不是非常相关,因为在单元测试角度控制器时,您应该实际处理带有$ scope的API,并将控制器方法视为私有(实现细节)。