我无法理解为什么以下代码无效。
index.html
<html>
<head lang="en">
<script src="../Scripts/angular.js"></script>
<script src="app/books/BooksController.js"></script>
<script src="app/services/dataService.js"></script>
</head>
<body ng-app="app">
<div ng-controller="BooksController as vm">
<h3>All Books</h3>
<div>
<ul>
<li ng-repeat="book in vm.allBooks">
{{ book.title }} - {{ book.author }}
</li>
</ul>
</div>
</div>
</body>
</html>
BookController.js
(function() {
var app = angular.module('app', []);
var BooksController = function(dataService) {
var vm = this;
vm.allBooks = dataService.getAllBooks;
}
app.controller('BooksController', ["dataService", BooksController]);
})();
dataService.js
(function() {
var app = angular.module('app');
var dataService = function() {
return {
getAllBooks: getAllBooks
};
var getAllBooks = function() {
return [{
book_id: 1,
title: "Harry Pptter and the Deathly Hallows",
author: "J.K. Rowling",
year_published: 2000
},
{
book_id: 2,
title: "The Cat in the Hat",
author: "Dr. Seuss",
year_published: 1957
},
{
book_id: 3,
title: "Encyclopedia Brown, Boy Detective",
author: "Donald J. Sobol",
year_published: 1963
}
];
};
}
app.factory('dataService', dataService);
})();
问题似乎是当我使用以下方法通过服务公开方法时:
return {
getAllBooks: getAllBooks
};
如果我将函数getAllBooks
的声明更改为如此,
function getAllBooks() {
...
}
并在我的控制器中调用服务:
vm.allBooks = dataService.getAllBooks()
它会正常工作。
我的问题是,为什么它不能用于声明函数并将它们放在变量中?是因为函数只是定义了,但实际上没有执行?
答案 0 :(得分:2)
这是因为函数表达式没有被提升,函数声明被挂起。
你只需要在函数表达式之后放置return语句。
所以把这个return语句放在函数表达式
之后return {
getAllBooks: getAllBooks
};
在javascript函数中可以挂起,这意味着你可以在声明它们之前使用它们。
但这仅限于函数声明,而不是函数表达式。
功能声明示例:
testFunction();//this will print this function is hoisted
function testFunction(){
console.log("this function is hoisted");
}
函数表达式示例:
testFunction(); //Error because testFunction expression is not hoisted
var testFunction = function(){
//this functions is not hoisted
}
有关提升这两个链接的更多信息非常有用 https://scotch.io/tutorials/understanding-hoisting-in-javascript http://adripofjavascript.com/blog/drips/variable-and-function-hoisting.html
答案 1 :(得分:1)
解决悬挂问题的另一种方法是以这种方式编写工厂。在工厂中创建一个对象,然后将每个方法附加到它,然后只返回该对象,您的方法将在您的控制器中可用。
(function() {
var app = angular.module('app');
var dataService = function() {
var factory = {};
factory.getAllBooks = function() {
return [];
};
return factory;
}
app.factory('dataService', dataService);
})();