1. UI闪烁问题
- 众所周知,Angular最大的亮点就是数据的双向绑定。然而,在项目的实际使用过程中,往往会碰到页面闪现出没有被解析的表达式(形如{{app.name}})。是因为在Angular初始化之前,DOM还没准备就绪,Angular正在计算并替换相应的值。 解决方法 1.1 放弃使用{{ }}表达式,改用ng-bind指令; 1.2 在元素上添加“ng-clock”,工作原理就是在初始化阶段inject了css规则,或者你可以包含这个css 隐藏规则到你自己的stylesheet。Angular就绪后就会移除这个cloak样式,让我们的应用(或者元素)立刻渲染。
2. ng-include指令
-
<div ng-include="views/include/footer.html"></div> 错在哪里,记得在第一次使用ng-include的时候,这样引用文件,始终在页面上都不显示footer.html的内容,后来明白ng-include需要的是一个变量,所以我们可以改写成<div ng-include="’views/include/footer.html’"></div> 或定义一个scope变量,如:scope变量,如:scope.footerHtml="views/include/footer.html"; 页面引用:<div ng-include="footerHtml"></div>。
究其原因是:因为在ng-include中,是把它的参数当做变量来解释的,它会通过$eval对传入的值进行计算,然后作为模板地址去加载。 不过,更好的方法是把这些界面片段(partical)写成指令,那样你就不用在多处重复写路径了,更重要的是,将来你可以直接在这里扩展它的交互逻辑,从界面原型平滑的演化到线上系统。 下面举一个写成指令的例子: HTML页面:页面中直接使用指令,指令会找到对应的页面进而进行DOM的渲染。
3. angularJS文件压缩问题
- 当项目上线时,我们往往需要将文件压缩以减少体积来提高页面的加载速度,普通的javascript压缩一般都没什么问题,但是如果是以下格式编码的angularJS文件压缩后,在使用则会报错:
解决办法是:使用Javascript数组方式构造控制器:把要注入的服务放到一个字符串数组(代表依赖的名字)里,数组最后一个元素是控制器的方法函数: varBookCtrl = ['scope′,′scope′,′http', function(scope,scope,http) { /* constructor body */}]; 如以下登陆的controller:
这样使用数组的方式在压缩后,就不会出现依赖的错误了。
4. IE11下get请求缓存问题,页面绑定数据不及时更新的bug
- 在项目开发的过程中,我曾经发现过一个奇葩的问题,就是在IE11浏览器下,当点击某个button触发一个函数,从而改变ng-model绑定的某个变量时,明确变量的值已经改变,但是只有在F12开启开发者调试工具时,页面才能及时更新显示改变后的变量值,一旦F12开发者调试工具关闭,变量值将不更新。但是这一现象在chrome、firefox下确不曾见,究其原因竟是IE浏览器下ajax请求缓存的问题,后来把缓存禁用后,竟恢复正常了。具体解决方法就是:在配置路由的angularJS文件中,添加如下配置代码即可:
5. $apply的使用
- 之前在微信端修改个人设置的页面时,接口没有返回用户的相关信息,只有通过另一个接口去获取用户的具体信息,但是这个过程中发现拿到用户的具体信息重新给$scope.userData赋值后,虽然model值改变了,但是页面并没有及时更新,主要原因是angular没有检测到数据变化,所以此时需要我们手动通知angular数据改变,如下代码所示:
6. jq的第三方插件问题
- Directive 就是在 HTML 里写自定义的标签属性,达到插件的作用,有效补充了HTML的功能。这种声明式的语法扩展了 HTML。建议项目中通用的功能和页面组件,都封装成Directive,方便使用和代码维护。
- DOM操作应该放在directive里面
7. $watch 和 $apply
- AngularJS 的双向数据绑定是最令人兴奋的特性了,然而它也不是全能的魔法,在某些情况下你需要做一些小小的修正。 当你使用 ng-model, ng-repeat 等等来绑定一个元素的值时, AngularJS 为那个值创建了一个 $watch,只要这个值在 AngularJS 的范围内有任何改变,所有的地方都会同步更新。而你在写自定义的 directive 时,你需要定义你自己的 $watch 来实现这种自动同步。 有时候你在代码中改变了 model 的值,view 却没有更新,这在自定义事件绑定中经常遇到。这时你就需要手动调用 scope.$apply() 来触发界面更新。上面 datepicker 的例子已经说明了这一点。第三方插件可能会有 call back,我们也可以把回调函数写成匿名函数作为参数传入$apply()中。
8. 子作用域的原型继承问题
- 对于初学者,这个也是个大坑啊。作用域变量的继承是基于javascript原型继承机制的,在使用涉及到作用域的指令如ng-template,ion-modal等时需要特别注意,相关的查找顺序这里就不细说了。
9.$rootScope 是可以用的,不过很可能被滥用
- Scopes 在 AngularJS 中形成一定的层级关系,树状结构必然有一个根节点。通常我们用不到它,因为几乎每个 view 都有一个 controller 以及相对应的自己的 scope。 但偶尔有一些数据我们希望全局应用在整个 app 中,这时我们可以将数据注入 $rootScope。因为其他 scope 都会继承 root scope,所以那些注入的数据对于 ng-show 这类 directive 都是可用的,就像是在本地 $scope 中的变量一样。 当然,全局变量是邪恶的,你必须很小心地使用 $rootScope。特别是不要用于代码,而仅仅用于注入数据。如果你非常希望在 $rootScope 写一个函数,那最好把它写到 service 里,这样只有用到的时候它才会被注入,测试起来也方便些。 相反,如果一个函数的功能仅仅是存储和返回一些数据,就不要把它创建成一个 service。