接近带给你AngularJS - 经验说明示例
接近带给你AngularJS列:
------------------------------------------------------------------------------------------------
之前我们已经介绍了全部的AngularJS 基础知识,下面让我们通过实例来加深记忆。体验自己定义指令的乐趣。
手风琴指令
我们展示的第一个样例是手风琴效果指令:
效果图例如以下:
在线实例地址:手风琴指令
不使用AngularJS的纯HTML源代码例如以下:
- <div class="accordion" id="accordion2">
- <div class="accordion-group">
- <div class="accordion-heading">
- <a class="accordion-toggle" data-toggle="collapse"
- data-parent="#accordion2" href="#collapseOne">
- Collapsible Group Item #1
- </a>
- </div>
- <div id="collapseOne" class="accordion-body collapse in">
- <div class="accordion-inner">
- Anim pariatur cliche...
- </div>
- </div>
- </div>
- <div class="accordion-group">
- <div class="accordion-heading">
- <a class="accordion-toggle" data-toggle="collapse"
- data-parent="#accordion2" href="#collapseTwo">
- Collapsible Group Item #2
- </a>
- </div>
- <div id="collapseTwo" class="accordion-body collapse">
- <div class="accordion-inner">
- Anim pariatur cliche...
- </div>
- </div>
- </div>
- </div>
以上纯 HTML源代码也能够实现手风琴效果,可是它不过一些标记,包括了大量的链接和id,不利于维护。
使用AngularJS自己定义指令结合下面HTML源代码相同能够得到预期效果:
- <body ng-app="btst">
- <h3>BootStrap手风琴指令</h3>
- <btst-accordion>
- <btst-pane title="<b>基本功能</b>" category="{name:'test'}">
- <div>AngularJS......</div>
- </btst-pane>
- <btst-pane title="<b>创建自己定义指令</b>">
- <div>使用过 AngularJS ......</div>
- </btst-pane>
- <btst-pane title="<b>体验实例</b>">
- <div>之前我们已经介绍了全部的AngularJS......</div>
- </btst-pane>
- </btst-accordion>
- </body>
这一版使用的HTML标记更少。看起来清晰且易维护。
下面。让我们看下指令写法。
首先,我们定义模块"btstAccordion" 指令:
- var btst = angular.module("btst", []);
- btst.directive("btstAccordion", function () {
- return {
- restrict: "E",
- transclude: true,
- replace: true,
- scope: {},
- template:
- "<div class='accordion' ng-transclude></div>",
- link: function (scope, element, attrs) {
- // 确保 accordion拥有id
- var id = element.attr("id");
- if (!id) {
- id = "btst-acc" + scope.$id;
- element.attr("id", id);
- }
- // set data-parent and href attributes on accordion-toggle elements
- var arr = element.find(".accordion-toggle");
- for (var i = 0; i < arr.length; i++) {
- $(arr[i]).attr("data-parent", "#" + id);
- $(arr[i]).attr("href", "#" + id + "collapse" + i);
- }
- // set collapse attribute on accordion-body elements
- // and expand the first pane to start
- arr = element.find(".accordion-body");
- $(arr[0]).addClass("in"); // expand first pane
- for (var i = 0; i < arr.length; i++) {
- $(arr[i]).attr("id", id + "collapse" + i);
- }
- },
- controller: function () {}
- };
- });
由于拥有内部HTML内容,所以设置指令的transclude 属性为true。模板使用ng-transclude 指令来声明相应的显示内容。由于模板中唯独一个元素,所以没有设置其它选项。
代码中最有趣的部分是link 方法。它在參数element具有id时启作用,假设没有,会根据指令的 Scope自己主动创建ID。一旦元素拥有了ID值,方法将通过jQuery来选择具有"accordion-toggle"类的子元素而且设置它的 "data-parent" 和 "href" 属性。最后,通过寻找“accordion-body” 元素,而且设置"collapse" 属性。
指令同一时候声明了一个拥有空方法的controller 。
声明controller 是必要的,由于Accordion会包括子元素,子元素将检測父元素的类型和controller 。
下一步须要定义手风琴选项卡的指令。
这一步比較easy,大多数操作将在这个模板中发生。可是它只须要少量的代码:
- btst.directive('btstPane', function () {
- return {
- require: "^btstAccordion",
- restrict: "E",
- transclude: true,
- replace: true,
- scope: {
- title: "@"
- },
- template:
- "<div class='accordion-group'>" +
- " <div class='accordion-heading'>" +
- " <a class='accordion-toggle' data-toggle='collapse'>{{title}}</a>" +
- " </div>" +
- "<div class='accordion-body collapse'>" +
- " <div class='accordion-inner' ng-transclude></div>" +
- " </div>" +
- "</div>",
- link: function (scope, element, attrs) {
- scope.$watch("title", function () {
- // NOTE: this requires jQuery (jQLite won't do html)
- var hdr = element.find(".accordion-toggle");
- hdr.html(scope.title);
- });
- }
- };
- });
require 属性值为"btstPane" ,所以该指令必须用于指令"btstAccordion"中。transclude 属性为true表明选项卡包括HTML标签。
scope 下的 "title" 属性将会被实例所替代。
这个样例中的模板比較复杂。
注意我们通过ng-transclude 指令来标记元素接收文本内容。
模板中"{{title}}" 属性将会显示标签名称。眼下我们只实现了纯文本显示,未定义其样式。我们使用link 方法能够替换标题为HTML源代码从而得到更丰富的样式。
就这样,我们完毕了第一个具有有用价值的指令。
它功能并不复杂可是足以展示一些AngularJS的重要知识点和技术细节:怎样定义嵌套指令,怎样生成唯一的元素ID,怎样使用jQuery操作DOM以及怎样使用$watch 方法监听scope变量的变化。
Google Maps 指令
下一个样例是创建Google地图的指令:
在我们创建指令之前。我们须要加入Google APIs 引用到页面中:
- <!-- required to use Google maps -->
- <script type="text/javascript"
- src="https://maps.googleapis.com/maps/api/js?sensor=true">
- </script>
接下来,我们创建指令:
- var app = angular.module("app", []);
- app.directive("appMap", function () {
- return {
- restrict: "E",
- replace: true,
- template: "<div></div>",
- scope: {
- center: "=", // Center point on the map
- markers: "=", // Array of map markers
- width: "@", // Map width in pixels.
- height: "@", // Map height in pixels.
- zoom: "@", // Zoom level (from 1 to 25).
- mapTypeId: "@" // roadmap, satellite, hybrid, or terrain
- },
center 属性进行了双向绑定。
这个应用能够改变地图中心和交互地图(当用户通过鼠标button选择地图位置时)。同一时候。地图也会在用户通过滚动选择地图位置时通知应用更新当前显示位置。
markers 属性被定义为引用由于它是数组形式,把它序列化为字符串比較耗时。link 方法能够实现下面功能:
1. 初始化地图
2. 在用户视图变量更改时更新地图
3. 监听事件
下面是实现代码:
- link: function (scope, element, attrs) {
- var toResize, toCenter;
- var map;
- var currentMarkers;
- // listen to changes in scope variables and update the control
- var arr = ["width", "height", "markers", "mapTypeId"];
- for (var i = 0, cnt = arr.length; i < arr.length; i++) {
- scope.$watch(arr[i], function () {
- if (--cnt <= 0)
- updateControl();
- });
- }
- // update zoom and center without re-creating the map
- scope.$watch("zoom", function () {
- if (map && scope.zoom)
- map.setZoom(scope.zoom * 1);
- });
- scope.$watch("center", function () {
- if (map && scope.center)
- map.setCenter(getLocation(scope.center));
- });
监測方法正如我们在文章開始时描写叙述的。变量发生变化后,它将调用updateControl 方法。updateControl 方法实际上使用selected 选项创建了新的地图。
"zoom" 和 "center" 变量将被分别处理。由于我们不希望每次在用户选择或缩放地图时都又一次创建地图。这两个方法检測地图是否又一次创建还是不过简单的更新。
下面是updateControl 方法的实现方法:
- // update the control
- function updateControl() {
- // get map options
- var options = {
- center: new google.maps.LatLng(40, -73),
- zoom: 6,
- mapTypeId: "roadmap"
- };
- if (scope.center) options.center = getLocation(scope.center);
- if (scope.zoom) options.zoom = scope.zoom * 1;
- if (scope.mapTypeId) options.mapTypeId = scope.mapTypeId;
- // create the map and update the markers
- map = new google.maps.Map(element[0], options);
- updateMarkers();
- // listen to changes in the center property and update the scope
- google.maps.event.addListener(map, 'center_changed', function () {
- if (toCenter) clearTimeout(toCenter);
- toCenter = setTimeout(function () {
- if (scope.center) {
- if (map.center.lat() != scope.center.lat ||
- map.center.lng() != scope.center.lon) {
- scope.center = { lat: map.center.lat(), lon: map.center.lng() };
- if (!scope.$$phase) scope.$apply("center");
- }
- }
- }, 500);
- }
updateControl 方法首先须要接收Scope设置相关參数。接着使用options 创建和初始化地图。这是创建JavaScript指令的常见模式。
创建地图之后,方法会在更新标记的同一时候加入检測事件。以便监视地图中心位置的变化。
该事件会监測当前的地图中心是否和Scope中的相同。假设不同。即会更新scope,调用$apply 方法通知AngularJS属性已经更改。
这样的绑定方式为双向绑定。
updateMarkers 方法十分的简单,差点儿和AngularJS分离,所以我们在这里就不介绍了。
除了这个地图指令特有的功能,这个样例还展示了:
1. 两个过滤器转换坐标为常规数字到地理位置,比如33°38'24"N, 85°49'2"W。
2. 一个地理编码器。转换成地址的地理位置(也是基于谷歌的API)。
3. 使用HTML5的地理定位服务来获取用户当前位置的方法。
Google地图 APIs 是极其丰富的。下面是一些资源入口:
Google地图APIs 文档: https://developers.google.com/maps/documentation/
Google许可条款:https://developers.google.com/maps/licensing
Wijmo Grid 指令
最后一个样例是可编辑的表格指令:
这里展示的图表插件是 Wijmo 前端插件套包中的一款插件 wijgrid 插件:
- <wij-grid
- data="data"
- allow-editing="true"
- after-cell-edit="cellEdited(e, args)" >
- <wij-grid-column
- binding="country" width="100" group="true">
- </wij-grid-column>
- <wij-grid-column
- binding="product" width="140" >
- </wij-grid-column>
- <wij-grid-column
- binding="amount" width="100" format="c2" aggregate="sum" >
- </wij-grid-column>
- </wij-grid>
"wij-grid" 指令定制表格的属性,"wij-grid-column" 指令定制特性表格列的属性。以上标记定义了一个拥有三列的可编辑表格。分别为:“country”。 "product" 和 "amount"。
而且,以country列分组而且计算每一个分组的合计。
这个指令中最特别的一点是 “wij-grid”和“wij-grid-column”的连接。为了使这个连接起作用,父指令中定义了例如以下controller:
- app.directive("wijGrid", [ "$rootScope", "wijUtil", function ($rootScope, wijUtil) {
- return {
- restrict: "E",
- replace: true,
- transclude: true,
- template: "<table ng-transclude/>",
- scope: {
- data: "=", // List of items to bind to.
- allowEditing: "@", // Whether user can edit the grid.
- afterCellEdit: "&", // Event that fires after cell edits.
- allowWrapping: "@", // Whether text should wrap within cells.
- frozenColumns: "@" // Number of non-scrollable columns
- },
- controller: ["$scope", function ($scope) {
- $scope.columns = [];
- this.addColumn = function (column) {
- $scope.columns.push(column);
- }
- }],
- link: function (scope, element, attrs) {
- // omitted for brevity, see full source here:
- // http://jsfiddle.net/Wijmo/jmp47/
- }
- }
- }]);
关于controller 方法使用前文中提到的数组语法声明,在这个样例中。controller定义了addColumn 方法。它将会被"wij-grid-column" 指令调用。父指令会通过特定标记来訪问列。
下面是"wij-grid-column" 指令的用法:
- app.directive("wijGridColumn", function () {
- return {
- require: "^wijGrid",
- restrict: "E",
- replace: true,
- template: "<div></div>",
- scope: {
- binding: "@", // Property shown in this column.
- header: "@", // Column header content.
- format: "@", // Format used to display numeric values in this column.
- width: "@", // Column width in pixels.
- aggregate: "@", // Aggregate to display in group header rows.
- group: "@", // Whether items should be grouped by the values in this column.
- groupHeader: "@" // Text to display in the group header rows.
- },
- link: function (scope, element, attrs, wijGrid) {
- wijGrid.addColumn(scope);
- }
- }
- });
require 成员用于指定"wij-grid-column" 指令的父级指令"wij-grid"。link 方法接收父指令的引用 (controller) 。同一时候通过addColumn 方法传递自身的scope 给父指令。
scope 包括了表格用于创建列的全部信息。
很多其它指令
链接为一些AngularJS 指令的在线实例: http://wijmo.gcpowertools.com.cn/demo/AngularExplorer/ 。你能够在样例的基础上进行练习。样例都是严格的安照本文中的描写叙述制作的。所以你能够无障碍学习他们。
资源推荐:
1. AngularJS by Google AngularJS主页。
2. AngularJS Directives documentation AngularJS 指令官方帮助文档。
3. AngularJS directives and the computer science of JavaScript 比較有用的AngularJS指令说明文章。
4. Video Tutorial: AngularJS Fundamentals in 60-ish Minutes AngularJS 介绍视频。
5. About those directives AngularJS 研发人员公布的视频教程。
6. Egghead.io AngularJS 使用系列视频教程。
7. Wijmo AngularJS Samples AngularJS 在线例子。
版权声明:本文博主原创文章,博客,未经同意不得转载。
接近带给你AngularJS - 经验说明示例的更多相关文章
- 带你走近AngularJS - 基本功能介绍
带你走近AngularJS系列: 带你走近AngularJS - 基本功能介绍 带你走近AngularJS - 体验指令实例 带你走近AngularJS - 创建自定义指令 ------------- ...
- 带你走近AngularJS - 体验指令实例
带你走近AngularJS系列: 带你走近AngularJS - 基本功能介绍 带你走近AngularJS - 体验指令实例 带你走近AngularJS - 创建自定义指令 ------------- ...
- 带你走近AngularJS - 创建自定义指令
带你走近AngularJS系列: 带你走近AngularJS - 基本功能介绍 带你走近AngularJS - 体验指令实例 带你走近AngularJS - 创建自定义指令 ------------- ...
- 带你走近AngularJS - 创建自己定义指令
带你走近AngularJS系列: 带你走近AngularJS - 基本功能介绍 带你走近AngularJS - 体验指令实例 带你走近AngularJS - 创建自己定义指令 ------------ ...
- 带你走近AngularJS 之创建自定义指令
带你走近AngularJS 之创建自定义指令 为什么使用AngularJS 指令? 使用过 AngularJS 的朋友应该最感兴趣的是它的指令.现今市场上的前端框架也只有AngularJS 拥有自定义 ...
- 5个示例带你学习AngularJS
直到现在,你或许已经听说过AngularJS了,一个改变你对web应用思考方式,由谷歌开发的令人兴奋的开源框架.关于它的文章已经写得非常之多,但我发现还是要写些给那些更喜欢快速且实际例子的开发者.当今 ...
- 前端MVC学习总结(四)——NodeJS+MongoDB+AngularJS+Bootstrap书店示例
这章的目的是为了把前面所学习的内容整合一下,这个示例完成一个简单图书管理模块,因为中间需要使用到Bootstrap这里先介绍Bootstrap. 示例名称:天狗书店 功能:完成前后端分离的图书管理功能 ...
- 前端MVC学习笔记(四)——NodeJS+MongoDB+AngularJS+Bootstrap书店示例
这章的目的是为了把前面所学习的内容整合一下,这个示例完成一个简单图书管理模块,因为中间需要使用到Bootstrap这里先介绍Bootstrap. 示例名称:天狗书店 功能:完成前后端分离的图书管理功能 ...
- NodeJS+MongoDB+AngularJS+Bootstrap书店示例
目录 一.Bootstrap 1.1.添加引用 1.2.在页面中使用BootStrap 1.3.可视化布局 二.使用MongoDB创建数据库 2.1.启动MongoDB数据库 2.2.启动数据库GUI ...
随机推荐
- Mutex(测量)
游标共享怎样使用Mutex kks 使用mutex以便保护对于下述基于parent cursor父游标和子游标child cursor的一系列操作 对于父游标parent cursor的操作: 基于发 ...
- 求1e11以内的素数
有两种做法,一种是打表,另一种是直接求. 打表 将1e11每隔len(len=2000w)个数字统计一下该区间内素数的个数,比如cnt[1] 表示[1,len]以内有多少个素数,cnt[2]表示[le ...
- 图画(txt等一下)实施开放的默认下载的默认浏览器,而不是(Java文本)
在网络上,假设我们超链接地址对应于jpg档,txt档,点击链接,默认浏览器打开这些文件,而不是下载,那么,你如何实现竞争力的默认下载. 1.可通过自己写一个download.jsp来实现 <%@ ...
- poj Budget
Budget 建图好题.不知道为什么提交一直TLE. 然后.该了几次,看了别人的普通网络流都过了. 我觉得可能是卡DINIC的某些部分吧.这题就是一道普通的上下界最小流. 建图麻烦,所以说一下建图吧. ...
- css实现自适应屏幕高度
body,html{ margin:0px; height:100%; }
- java整合flex
java+flex项目整合 评论0 字号:大中小 订阅 第一种:javaproject和flexproject独立 这样的方式也是非常多人使用的方式.flex程序猿和java程序猿相互独立的工作. ...
- 设计模式之迭代器模式(Iterator)摘录
23种GOF设计模式一般分为三大类:创建型模式.结构型模式.行为模式. 创建型模式抽象了实例化过程,它们帮助一个系统独立于怎样创建.组合和表示它的那些对象.一个类创建型模式使用继承改变被实例化的类,而 ...
- oracle 11g impdp时 报ORA-12899(转)
源库ZHS16BGK,汉字在数据库存放的时候占用两个字节 目标库UTF8,汉字在数据库里存放的时候占用三个字节 由于字符集不同,导致现在数据库impdp的时候有些表的字段长度不够,出现ORA-1289 ...
- FS SIP呼叫的消息线程和状态机线程
THREAD 当收到一次呼叫的时候,FS会在TU层创建两个线程,一个线程为状态机线程,另外一个为消息线程.状态机线程通过switch_core_session_thread_launch创建,顾名思义 ...
- 【原创】leetCodeOj --- Sliding Window Maximum 解题报告
天,这题我已经没有底气高呼“水”了... 题目的地址: https://leetcode.com/problems/sliding-window-maximum/ 题目内容: Given an arr ...