上周刚开始入坑angularjs,学习期间做了一些小练习巩固知识点,期间也碰到了一下小坑,做个简单记录:
1.注入服务时请使用数组注入方式,避免编译后注入失败:
Good:
Bad:
2.自定义或js预定义函数无法触发页面更新问题:
请自行先详细了解digest()循环原理。
原因及解决方式:自定义或js预定义函数无法触发脏检查,需手动调用$digest()或使用$apply()
or
3.自定义指令中scope绑定父作用域变量不生效问题:
父作用域$scope属性请分条定义,不能使用对象直接覆盖$scope
4.自定义指令参数scope、controller&link
scope: @绑定简单的父作用域属性,单向绑定
=双向绑定父作用域属性
&提供一种方式执行父作用域上下文中的表达式,用于绑定父作用域中的函数
controller&link:都可以通过函数实现业务逻辑
区别:controller执行于编译之前(视图呈现前),link执行于编译之后,所以controller多用于准备视图层数据或与其他指令进行数据业务交互逻辑,link多用于DOM操作
5.ng-bind 与{{ xxx }}表达式的取舍
建议使用ng-bind代替{{ xxx }}表达式,避免表达式未生效时视图显示出{{}}
Tips:通过ng-bind的数据绑定方式同样可以使用filter
附上前辈编写的练习demo:
1.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <style> 7 </style> 8 </head> 9 <!-- 功能要求: --> 10 <!-- 每次点击button,win中就把计数加一,记录button的点击次数 --> 11 <!-- 样式自己补充,如需要,将css放到本文件夹中单独的css文件中,不要写在html中 --> 12 <body ng-app="main"> 13 <div class="container" ng-controller="ctrl"> 14 <div class="win"></div> 15 <button>累加</button> 16 </div> 17 <script src="../../lib/angular-1.5.6.js"></script> 18 <script> 19 var mian = angular.module('main', []); 20 mian.controller('ctrl', ['$scope', function ($scope) { 21 22 }]); 23 </script> 24 </body> 25 </html>
2.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <style> 7 </style> 8 </head> 9 <!-- 功能要求: --> 10 <!-- 实现一个时间显示器,显示时分秒,如14:30:00,每过一秒刷新一次,在cur-time中显示 --> 11 <!-- 样式自己补充,如需要,将css放到本文件夹中单独的css文件中,不要写在html中 --> 12 <!-- 考察内置filter,service的注入及使用 --> 13 <body ng-app="main"> 14 <div class="container" ng-controller="ctrl"> 15 <div class="cur-time"></div> 16 </div> 17 <script src="../../lib/angular-1.5.6.js"></script> 18 <script> 19 var mian = angular.module("main", []); 20 mian.controller("ctrl", ["$scope", function ($scope) { 21 22 }]); 23 </script> 24 </body> 25 </html>
3.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <style> 7 </style> 8 </head> 9 <!-- 功能要求: --> 10 <!-- 在t1中输入英文字符串,在t2中将字符转换成大写实时显示,点击清空按钮后将t1、t2内容清空 --> 11 <!-- 样式自己补充,如需要,将css放到本文件夹中单独的css文件中,不要写在html中 --> 12 <!-- 主要考察内置指令-双向绑定的使用 --> 13 <body ng-app="main"> 14 <div class="container" ng-controller="ctrl"> 15 <textarea class="t1"></textarea> 16 <textarea class="t2"></textarea> 17 <button>清空</button> 18 </div> 19 <script src="../../lib/angular-1.5.6.js"></script> 20 <script> 21 var mian = angular.module("main", []); 22 mian.controller("ctrl", ["$scope", function ($scope) { 23 24 }]); 25 </script> 26 </body> 27 </html>
4.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <style> 7 </style> 8 </head> 9 <!-- 功能要求: --> 10 <!-- 在t1中输入数字,如果数字的奇偶性发生变化则在t2中把t1中的数字显示出来 --> 11 <!-- 用$watch实现该功能,不要用onchange事件 --> 12 <!-- 样式自己补充,如需要,将css放到本文件夹中单独的css文件中,不要写在html中 --> 13 <!-- 主要考察$watch的使用和脏检查机制 --> 14 <body ng-app="main"> 15 <div class="container" ng-controller="ctrl"> 16 <input class="t1"> 17 <textarea class="t2"></textarea> 18 </div> 19 <script src="../../lib/angular-1.5.6.js"></script> 20 <script> 21 var mian = angular.module('main', []); 22 mian.controller('ctrl', ['$scope', function ($scope) { 23 24 }]); 25 </script> 26 </body> 27 </html>
5.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <style> 7 </style> 8 </head> 9 <!-- 功能要求: --> 10 <!-- 1.开发一个任务列表,用AngularJS的$http服务发送ajax请求从服务器端获取数据,请求url是http://127.0.0.1:3000/getData.ajax --> 11 <!-- 2.返回的数据里是个数组,每项包含title和value,每项对应列表中的一行,将title和value渲染出来 --> 12 <!-- 3.每一行加一个删除按钮,点击后该行从列表中被删除,删除不用向服务器发送请求 --> 13 <!-- 服务器需要用nodejs启动本文件夹下的server.js --> 14 <body ng-app="main"> 15 <div class="container" ng-controller="ctrl"> 16 <table> 17 <thead> 18 <tr> 19 <td>title</td> 20 <td>value</td> 21 <td>operate</td> 22 </tr> 23 </thead> 24 <tbody> 25 26 </tbody> 27 </table> 28 </div> 29 <script src="../../lib/angular-1.5.6.js"></script> 30 <script> 31 var mian = angular.module('main', []); 32 mian.controller('ctrl', function ($scope) { 33 34 }) 35 </script> 36 </body> 37 </html>
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 var http = require('http'); 2 var url = require("url"); 3 var fs = require("fs"); 4 5 var hostname = '127.0.0.1'; 6 var port = 3000; 7 function makeTile() { 8 var str = ''; 9 var len = Math.random() * 10 + 5; 10 for (var i = 0; i < len; i++) { 11 str += String.fromCharCode(20000 + Math.random() * 1000 << 0); 12 } 13 return str; 14 } 15 var server = http.createServer(function (req, res) { 16 var urlObj = url.parse(req.url); 17 var pathname = urlObj.pathname; 18 var data; 19 switch (pathname) { 20 case "/getData.ajax": 21 res.statusCode = 200; 22 data = { 23 status: 0, content: [], message: '' 24 }; 25 for (var i = 0; i < 10; i++) { 26 data.content.push({ 27 title: makeTile(), 28 value: Math.random() * 10000 << 0 29 }); 30 } 31 res.setHeader('Content-Type', 'application/json; charset=utf-8'); 32 res.setHeader('Access-Control-Allow-Origin', '*'); 33 res.write(JSON.stringify(data)); 34 break; 35 default: 36 res.statusCode = 404; 37 } 38 res.end(); 39 }); 40 41 server.listen(port, function () { 42 console.log("Server running"); 43 });
6.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <!DOCTYPE html> 2 <html lang="en"> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Title</title> 6 <style> 7 8 </style> 9 </head> 10 <!-- 功能要求: --> 11 <!-- 功能同练习5,区别是将$http获取数据抽象成一个公共函数,做成service, --> 12 <!-- service单独放到另外一个模块中(module),这个模块单独放在另外一个js文件moduleAjax.js中 --> 13 <!-- 练习目的:经过这个联系熟悉多个模块的使用、service的使用、自定义service的注入 --> 14 15 <body ng-app="main"> 16 <div class="container" ng-controller="ctrl"> 17 <table> 18 <thead> 19 <tr> 20 <td>title</td> 21 <td>value</td> 22 <td>operate</td> 23 </tr> 24 </thead> 25 <tbody> 26 27 </tbody> 28 </table> 29 </div> 30 <script src="../../lib/angular-1.5.6.js"></script> 31 <script> 32 var mian = angular.module('main', []); 33 mian.controller('ctrl', ['$scope', function ($scope) { 34 35 }]); 36 </script> 37 </body> 38 </html>
7.
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 <!DOCTYPE html> 2 <html lang="en"> 3 4 <head> 5 <meta charset="UTF-8"> 6 <title>Title</title> 7 <style> 8 9 </style> 10 </head> 11 <!-- 功能要求: --> 12 <!-- 自己用div写一个带过滤检索功能的下拉框,样式见本文件夹下的图片 13 把这个带检索功能的下拉框封装成一个组件(directive) 14 接受的参数是一个数组[{name:'下拉框中显示的名称,可能重复',code:'数值,每个name有个唯一的code'}] 15 需要能够让使用者知道下拉框被选中的项目发生变化,可以提供onchange回调,也可以用ng-model暴露curItem让用户自己去watch变化,数据可以自己构造假数据 --> 16 <!-- 主要考察组件型指令的封装及使用 --> 17 <body ng-app="main"> 18 <div class="container" ng-controller="ctrl"> 19 <div class="win"> 20 21 </div> 22 </div> 23 <script src="../../lib/angular-1.5.6.js"></script> 24 <script> 25 var mian = angular.module('main', []); 26 mian.controller('ctrl', ['$scope', function ($scope) { 27 28 }); 29 </script> 30 </body> 31 </html>
练习7结果参考图:
以上练习题都比较简单,但是可以为刚开始入门的初学者理清相关的知识点,加深概念,在此感谢一下为我编写练习题的导师群哥。
由于题目比较简单,我这里就不附答案了,仅对练习7给出一个参考链接:
https://www.cnblogs.com/jackicalSong/p/5824671.html
如需要答案请私信博主。
注:本文仅为博主自己学习angularjs1.x时所作简单个人总结,随着学习的深入,本人也会逐步更新。
如有错误,敬请指正!也随时欢迎同好留言私信交流!