Angular.js入門 (4)ディレクティブ その1Angular.js入门(4)指令 第一部分
前次: Angular.js入门(3)过滤器
下次: Angular.js入门(5)指令 第二部分
这次终于要谈到Angular.js中非常重要的directive了。特别是因为”directive”这个词在日语中不常见,所以理解起来可能有些困难呢(^ω^;)。
不仅可以自己创建自定义的指令,就像过滤器一样,Angular本身还具有默认的指令。让我们首先看看使用这些指令可以做什么。
第一次指令
var app = angular.module("myApp", []);
app.directive("test", function () {
return {
restrict: "E",
template: "<div>これはテストだよ!</div>"
}
})
首先从JavaScript开始。
在app中添加一个指令(directive),将指令名为”test”和一个函数作为参数传递。函数将返回一个具有restrict和template属性的对象。
<!doctype html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Angular.jsのテスト</title>
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/foundation/5.2.2/css/foundation.css">
</head>
<body>
<div ng-app="myApp">
<test></test>
</div>
</body>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.6/angular.js"></script>
<script type="text/javascript" src="main.js"></script>
</html>
接下来,在html中,在ng-app内部,尝试编写一个由js中指定的directive名为”test”的标签。当在浏览器中打开index.html时,
![はじめてのDirective](https://cdn.silicloud.com/blog-img/blog/img/657d3aa737434c4406c7ec06/8-0.png)
在test标签中可以看到作为模板指定的内容。
Directive有着“指令”或“命令”的意思,但实际上它是一种不同于jQuery的方式来描述操纵某个DOM元素的命令。建议将其想象为一种命令,用于操作特定的DOM元素。
以下はその属性に制限を設けることを意味しています。
-
- “test”という名前の要素(“E”)を持つDOMは
-
- テンプレートとして”
“というテンプレートを使え!
という命令になるわけです。
让我们也看看其他的例子吧。
var app = angular.module("myApp", []);
app.directive("test", function () {
return {
restrict: "A",
link: function () {
alert('これはテストです!');
}
};
});
这次限制是“A”属性。link通常用于分配不同事件监听器,比如点击等。但这次只需要将其关联到一个输出alert的函数上即可,不需要其他处理。
<!doctype html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Angular.jsのテスト</title>
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/foundation/5.2.2/css/foundation.css">
</head>
<body>
<div ng-app="myApp">
<div test></div>
</div>
</body>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.6/angular.js"></script>
<script type="text/javascript" src="main.js"></script>
</html>
请注意属性限制下,将 ”
” 和 “test” 更改为属性的事实。打开浏览器后
![はじめてのDirective2](https://cdn.silicloud.com/blog-img/blog/img/657d3aa737434c4406c7ec06/18-0.png)
会出现一个警报。
另外一个选项。
app.directive("test", function () {
return {
restrict: "C",
link: function () {
alert('これはテストです!');
}
};
});
这次是C班,限制在C班的情况下
<div ng-app="myApp">
<div class="test"></div>
</div>
当写成「と」时,同样会显示警报。
如果省略`restrict`属性,则会应用默认的属性限制A。可以预期A的使用频率最高。
一个实用的Directive的例子
让我们看一下在上面的链接中说要编写事件监听器。
var app = angular.module("myApp", []);
app.directive("enter", function () {
return {
restrict: "A",
link: function (scope, element) {
element.bind("mouseenter", function () {
console.log('マウスin');
});
}
};
});
在此链接中指定的函数接受scope和element作为参数。请暂时忽略scope。element保持不变,在此处指定的”enter”属性将绑定到拥有”mouseenter”事件的元素上,并输出console.log函数。
<!doctype html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Angular.jsのテスト</title>
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/foundation/5.2.2/css/foundation.css">
</head>
<body>
<div ng-app="myApp">
<div enter>この上にマウスを乗せてみる。</div>
</div>
</body>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.6/angular.js"></script>
<script type="text/javascript" src="main.js"></script>
</html>
我也创建了一个具有enter属性的div元素,以便在html中进行对应。
实际上,你可以尝试将鼠标悬停在文本上方,可以确认控制台已输出内容。
![マウスオーバー](https://cdn.silicloud.com/blog-img/blog/img/657d3aa737434c4406c7ec06/32-0.png)
因为与此类事件相关的处理非常常见,所以也提供了一种更简单的编写链接的方法。
首先,由于默认情况下,restrict是A的,所以我们可以省略它。
var app = angular.module("myApp", []);
app.directive("enter", function () {
return {
link: function (scope, element) {
element.bind("mouseenter", function () {
console.log('マウスin');
});
}
};
});
当没有其他指定选项时,可以直接返回函数而不写入链接,其效果相同。
var app = angular.module("myApp", []);
app.directive("enter", function () {
return function (scope, element) {
element.bind("mouseenter", function () {
console.log('マウスin');
});
};
});
我们再添加一个事件,当鼠标离开时。
var app = angular.module("myApp", []);
app.directive("enter", function () {
return function (scope, element) {
element.bind("mouseenter", function () {
console.log('マウスin');
});
};
});
app.directive("leave", function () {
return function (scope, element) {
element.bind("mouseleave", function () {
console.log('マウスout');
});
};
});
对应的div也要添加”leave”属性。
<!doctype html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Angular.jsのテスト</title>
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/foundation/5.2.2/css/foundation.css">
</head>
<body>
<div ng-app="myApp">
<div enter leave>この上にマウスを乗せてみる。</div>
</div>
</body>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.6/angular.js"></script>
<script type="text/javascript" src="main.js"></script>
</html>
当你将鼠标放在文本上并移开时,试试看
![in and out](https://cdn.silicloud.com/blog-img/blog/img/657d3aa737434c4406c7ec06/42-0.png)
你可以看到兩邊都在動,對吧?
让我们以一个更实用的例子来将鼠标放在上面时改变用户界面的处理。
var app = angular.module("myApp", []);
app.directive("enter", function () {
return function (scope, element) {
element.bind("mouseenter", function () {
element.addClass("panel");
});
};
});
app.directive("leave", function () {
return function (scope, element) {
element.bind("mouseleave", function () {
element.removeClass("panel");
});
};
});
在Angular中,虽然出现了addClass和removeClass这样的jQuery函数,可能会让人有些意外。但是,Angular中包含了一个名为jqLite的jQuery子集,所以部分类似的函数也可以使用。
Panel类会根据加载的CSS框架进行面板样式的装饰。将鼠标悬停在文本上方时,您可以看到
![実用的なDirective](https://cdn.silicloud.com/blog-img/blog/img/657d3aa737434c4406c7ec06/48-0.png)
我可以看出它有一个富有的面板外观。
这样也可以,但在Angular中可以更加简洁地编写,可以在HTML中直接编写panel类,而不是在directive中直接编写。
<!doctype html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<title>Angular.jsのテスト</title>
<link rel="stylesheet" href="http://cdnjs.cloudflare.com/ajax/libs/foundation/5.2.2/css/foundation.css">
</head>
<body>
<div ng-app="myApp">
<div enter="panel" leave>この上にマウスを乗せてみる。</div>
</div>
</body>
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.6/angular.js"></script>
<script type="text/javascript" src="main.js"></script>
</html>
请注意属性”enter”的取值中包含”panel”。您可以通过以下方式在js中获取它。
var app = angular.module("myApp", []);
app.directive("enter", function () {
return function (scope, element, attrs) {
element.bind("mouseenter", function () {
element.addClass(attrs.enter);
});
};
});
app.directive("leave", function () {
return function (scope, element, attrs) {
element.bind("mouseleave", function () {
element.removeClass(attrs.enter);
});
};
});
请注意,链接的参数中新增了attrs。通过指定这个参数,可以通过attrs.enter来获取panel。
这个结果和上面的一样,但是这个选项更好的体现了统一感,因为它包括了关于用户界面的数值在HTML部分,而且指令方面也更容易进行单元测试,可以写得更漂亮!
关于directive部分还有一点需要补充,在下次继续讨论。