这里发生的事情有点太多,无法完全解释每一个,所以我将尝试对每一个进行简短的解释并举一个例子。
控制器
使用控制器来处理视图的逻辑并分配要在视图中显示的数据。例如,如果在您的应用程序中,您有一个名为“所有用户”的页面,您想要显示用户列表,请定义一个用户数组并将其附加到$scope
控制器中的对象。
var myApp = angular.module('myApp',[]);
myApp.controller('allUsersController', ['$scope', function($scope) {
$scope.users = [
{ name: "User 1", id: 1},
{ name: "User 2", id: 2},
{ name: "User 3", id: 3}
];
}]);
将 users 数组附加到范围允许您从视图访问此数据。所以现在在视图中你可以使用NG-重复 https://docs.angularjs.org/api/ng/directive/ngRepeat输出用户列表:
<ul>
<li ng-repeat="user in users">{{user.name}}</li>
<ul>
指令
指令主要用于两件事:
- 创建可重用组件
- 操作 DOM
指令一开始使用起来很棘手,但非常强大,文档中的这一声明是它们如此强大的原因:
指令是 DOM 元素上的标记(例如
属性、元素名称、注释或 CSS 类)告诉 AngularJS
HTML 编译器 ($compile) 将指定的行为附加到该 DOM
元素(例如通过事件监听器),甚至转换 DOM
元素及其子元素。
主要的一点是,指令允许您将特定的逻辑/行为附加到特定的element,因为控制器通常只允许您将逻辑附加到页面/视图。
假设在前面的示例中,我们想要添加一些可以在用户列表中完成的操作,可能是喜欢和不喜欢按钮。我们可以像这样创建喜欢和不喜欢按钮:
JS
var myApp = angular.module('myApp',[]);
myApp.controller('allUsersController', ['$scope', function($scope) {
$scope.users = [
{ name: "User 1", id: 1, like: 0},
{ name: "User 2", id: 2, like: 0},
{ name: "User 3", id: 3, like: 0}
];
$scope.like = function(user){
user.like++;
}
$scope.dislike = function(user){
user.like--;
}
}]);
HTML
<ul>
<li ng-repeat="user in users">
{{user.name}}
<button ng-click="like(user)">LIKE</button>
<button ng-click="dislike(user)">DISLIKE</button>
</li>
<ul>
相当简单,我们在控制器中添加喜欢/不喜欢的方法,以增加/减少用户的喜欢数量。这段代码可以正常工作,但是如果我想在不同的视图中创建另一个用户列表怎么办?假设您有 3 个不同的视图,其中包含用户列表:“所有用户”、“我的朋友”和“推荐用户”,所有 3 个视图都会有一个具有相同操作(喜欢或不喜欢)的用户列表,但显示的用户是每个都不同。我们想要使用我们在我们的代码中定义的相同的喜欢/不喜欢方法allUsersController
但我们处于不同的视图上,因此我们无法访问它们,因此您必须将相同的代码复制到其他视图的控制器中,在我们的示例中可能看起来不是什么大问题,但随着应用程序变得更大、更复杂这变得非常乏味且难以维护。
这就是指令发挥作用的地方,您可以在指令中定义它,而不是在控制器中分配每个用户项背后的逻辑:
app.directive('userItem', function() {
return {
template: '<div>{{userData.name}} <button ng-click="like()">Like</button> <button ng-click="dislike()">Dislike</button>',
scope: {
userData: "="
},
link: function(scope, element, attrs) {
scope.like = function(){
scope.userData.like++;
}
scope.dislike = function(){
scope.userData.like--;
}
}
}
});
在你的html中:
<div class="user_list>
<user-item ng-repeat="user in users" user-data="user"></user-item>
</div>
通过使用user-item
现在,您可以在应用程序中的任何位置创建用户列表,而无需重新定义每个用户的逻辑。您会注意到,这也稍微清理了我们的 html,并节省了很多重复代码的时间。该指令将您的 html 和 js 包装成reusable成分。
EDIT:关于我们如何将用户数据传递给指令,这与指令中的隔离范围有关,您可以阅读有关内容here http://weblogs.asp.net/dwahlin/creating-custom-angularjs-directives-part-2-isolate-scope。基本思想是,它将指令的范围与父范围(在我们的例子中为 allUsersController)隔离,这样做是为了避免两个范围中的数据之间出现不必要的冲突并促进可重用性。但同时我们希望控制器与指令共享一些数据,因此我们通过隔离范围“戳一个洞”以允许某些内容进入,在我们的例子中是userData
在指令范围内定义。
您可以访问指令文档 https://docs.angularjs.org/guide/directive并向下滚动以隔离范围以获取更多示例。