阅读更多

7顶
1踩

Web前端

转载新闻 AngularJS最佳编码实践指南

2014-12-11 11:20 by 正式编辑 cao345657340 评论(6) 有7496人浏览
AngularJS 是制作 SPA(单页面应用程序)和其它动态Web应用最广泛使用的框架之一。我认为程序员在使用AngularJS编码时有一个大的列表点应该记住,它会以这样或那样的方式帮助到你。下面是一些我遵守的最佳实践建议,同时也想推荐给你们。 我坚信有更多的功能也应该是这份列表的一部分,我邀请你们都来提建议或者在下面评论,从而使这个成为完整的最佳实践指南。

一、依赖注入:

1. 依赖注入是AngularJS框架最好的特性之一,我们应该经常使用它。当我们需要对我们的应用程序进行测试用例覆盖时,它将真正的起到帮助。

2. 为依赖提供别名,这样他们不会在(JS代码)压缩过程中重命名,因为在AngularJS依赖是通过命名来实现的(注:AngularJS通过控制器构造函数的参数名字来推断依赖服务名称的)。
angular.module(‘myApp’).controller('MyController', ['$scope',  'MyService',function($scope, MyService) {
 
    // controller logic
 
    }
   ]);

二、作用域

1. 在templates(模板)中scope(作用域)按只读对待。这就是说即使AngularJS允许我们在templates中编写代码修改scope,我们必须非常谨慎或者就不应该做。

2. 在controllers(控制器)中scope按只写对待。这就是说一个controllers负责使用另一个组件,就像一个服务,获取template 将要显示的数据和把数据写到scope的一个对象中。

  • 作为一个经验法则,我们必须总是在绑定时使用”.“。这就是说我们应该绑定到scope的对象,而不是直接的属性,否则可能会在子$scope导致意外的行为,因为$scope基于Java-script的原型继承机制。
  • 下面的代码我们可以看到,superhero是scope上一个通过Superhero服务返回的对象,同时相同的对象被用来绑定在view(视图)上。

<div class="form-group">
    <label class="control-label" for="name">Super Power</label>
       <div class="controls">
      <input type="text" data-ng-model="superhero.superPower">
</div>


$scope. superhero = Superheros.get({
    superheroId: $stateParams.superheroId
)};

  • Scope 的目的是引用 model,而不是成为 model。
  • Model是我们的JavaScript对象

三、验证

1. 在form(表单)标签中使用“novalidate” 属性来使用 AngularJS验证同时关闭HTML5验证。
<form name="reviewForm" ng-controller="ReviewController as reviewCtrl" ng-submit="reviewCtrl.addReview(product)" novalidate>

2. 我们可以使用angular classes(css类)来改变可见性和验证控件的状态。
.ng-valid.ng-dirty{
    border-color: #FA787E;
}
.ng-invalid.ng-dirty{
    border-color: #FA787E;
}

四、内存 – 任务管理

  • AngularJS在销毁一个scope和把一个scope从它的父级移除之前会广播一个$destroy事件。监听这个事件对清理任务和资源是至关重要的,否则可能会继续消耗内存或CPU。总是注册‘destroy‘事件来删除任何易于内存泄漏的代码。
作为一个例子,下面的控制器在1秒的间隔不断更新一个mode(模型)l值,这些更新将永远持续,即使在controller对应view消失了或者scope从父级上移除。如果用户来回导航到一个view来加载这个controller,每次导航将添加另一个永远运行的计时器。
module.controller("MyController", function($scope, $timeout) {
    var onMyTimeout = function() {
        $scope.value += 1;
        $timeout(onMyTimeout, 100);
    };
    $timeout(onMyTimeout, 100);
    $scope.value = 0;
 
});

监听$destroy事件是停止计时器的一个机会。一种方法是取消由$timeout返回的promise(承诺)。
module.controller("TestController", function($scope, $timeout) {var onTimeout = function() {
    $scope.value += 1;
    timer = $timeout(onTimeout, 100);
};
 
    var timer = $timeout(onTimeout, 100);
    $scope.value = 0;
    $scope.$on("$destroy", function() {
 
        if (timer) {
            $timeout.cancel(timer);
        }
    });
});

五、事件 顶级作用域

1. 我们应该只在当前屏幕的单页面应用程序的控制器中使用scope 事件进行通信。如果我们只需要共享数据,那么我们应该考虑使用Services(服务)。

2. 当触发事件时,除非我们需要把事件通知到我们整个应用程序里的所有单个scope,否则我们不需要在$rootScope触发事件。如果我们只需要为子scope触发,则在当前的scope上$broadcast事件。父scope使用$emit获取当前scope事件。这也将缩短事件传播,而不是经过整个自上而下的流动。

3. Services 是在$rootScope监听事件获取通知的不二选择。这是因为services在我们的应用程序中只初始化一次,并没有获取它们自己的scope ,这将是很好。

4. 通常我们不应该在$rootScope注册事件监听(除了service)。这是导致AngularJS应用程序产生bug的一个普遍原因。这是因为当我们在一个controller 的$scope上添加一个事件监听,而controller 被销毁(我们导航离开页面,或关闭一个部分),监听同样被销毁。当我们将它添加到$rootScope,同时导航离开一个controller,监听会保留并保持活动和触发。所以我们必须从$rootScope手动取消监听,或者为了安全干脆就不在$rootScope上添加监听。但是如果我们必须为$rootScope添加一个事件,不要忘记在controller的scope中将其清除。
<strong> </strong>
 
var myEventHandler = $rootScope.$on('MyEvent', ‘My Data’);
      $scope.$on('$destroy', function() {
      myEventHandler();
});

5. 如果我们知道只有一个监听器,而且你已经遇到了。我们可以通过在传递给事件监听函数的事件对象上调用event.stopPropagation()来停止进一步的事件传播。

六、构建业务逻辑

1. Controllers 不应该引用DOM,而只是包含行为,使用Directives (指令)做DOM操作。

2. Services应该对view逻辑独立.

3. 不要与HTML打架,而是通过Directives扩展。

4. 最好是使用模块化的文件夹结构,这样我们可以创建可重用的/可分发的组件。

七、通用规则

1. 对images使用ng-src 替代src。

2. 使用promise 来处理回调。AngularJS已经为它暴露了“$q”服务。许多AngularJS services返回promises:$http, $interval, $timeout。

3. 不要压缩angular.min.js 因为AngularJS团队已经通过预定义设置压缩了angular文件,如果我们再压缩可能会产生破坏。所以直接使用。

4. 如果template (模板)缓存是必需的,使用$templateCache缓存html template。

5. 总是把第三方API的回调包裹到$apply,用来通知AngularJS关于环境的变化。

6. 如果我们不想让用户在AngularJS加载之前显示HTML ,使用ng-cloak directive。
<div class="session ng-cloak">..............content............</div>
.ng-cloak {
/* this will change to block when scope and angular is ready */
display:none;
}

7. 为了阻止任何冲突,不要在我们自己的directives里使用“ng”前缀。创建你的自定义的。最好使用<my-component> ,因为 <my:component>在IE有时出错。
<my-component>
<my:component>

8. 在应用程序中为全局相关的事件使用$broadcast() , $emit() 和 $on()(比如用户身份验证或应用程序关闭)。如果我们需要特定于模块,服务或小部件的事件,我们应该选择Services,Directive Controllers等。

9. 不要使用自动关闭标签,因为有些浏览器不喜欢他们。使用“<product-title></product-title >”而不是“<product-title/>”。
来自: 伯乐在线
7
1
评论 共 6 条 请登录后发表评论
6 楼 鲍鱼啊 2015-11-20 18:14
[flash=200,200][url][img][list]
[*]
引用
[b][i][u]
[*][flash=200,200][url][img][list]
[*][*]
引用
[u][i][b][/b][/i][/u]
  • [/list][/img][/url][/flash]
    [*]
    [/u][/i][/b]
    ||[/list][/img][/url][/flash]|
    5 楼 gxb_1985 2014-12-16 16:24
    hdzhanghaoran 写道
    最近在用感觉 整体在实际开发过程中代码风格比较不适应,它要在jsp页面定制一个actoin 然后再写个控制层  还需要写个service 层 .这样js数量会很多,可能我使用ajax一个方法就调用了,而使用这个 爱裹乱 js 确实让人感觉挺反感 并且前台代码在维护性 也比较浮躁.仅代表个人观点.


    你这个不符合angularjs的用法,使用angularjs的都是单页应用,配合后端restful api的。
    https://github.com/gxbcj/SPA-by-AngularJS
    4 楼 hdzhanghaoran 2014-12-15 10:47
    最近在用感觉 整体在实际开发过程中代码风格比较不适应,它要在jsp页面定制一个actoin 然后再写个控制层  还需要写个service 层 .这样js数量会很多,可能我使用ajax一个方法就调用了,而使用这个 爱裹乱 js 确实让人感觉挺反感 并且前台代码在维护性 也比较浮躁.仅代表个人观点.
    3 楼 mike8625 2014-12-13 13:19
    jimxl 写道
    mike8625 写道
    angularjs就是把简单问题复杂化~连dom都不能自由操作的反人类开发框架~语言都是越来越简单~它是越搞越复杂~不看好它

    二货

    别人身攻击~有事说事~要说二我觉得你更二吧~二楼的兄弟
    2 楼 jimxl 2014-12-12 19:28
    mike8625 写道
    angularjs就是把简单问题复杂化~连dom都不能自由操作的反人类开发框架~语言都是越来越简单~它是越搞越复杂~不看好它

    二货
    1 楼 mike8625 2014-12-12 18:06
    angularjs就是把简单问题复杂化~连dom都不能自由操作的反人类开发框架~语言都是越来越简单~它是越搞越复杂~不看好它

    发表评论

    您还没有登录,请您登录后再发表评论

    相关推荐

    • Mysql解决数据库N+1查询问题

      假如查询出n个user,那么需要做n次查询dept,查询user是一次select,查询user关联的 dept,是n次,所以是n+1问题,其实叫1+n更为合理一些。 mybatis配置 UserMapper.xml &lt;result column

    • Hibernate框架操作MySQL数据库查询修改数据例子

      最近接手的项目使用Hibernate框架操作MySQL数据库,就想记录一下基本操作,以下是查询、修改数据的例子: public class HibernateData { private static final Logger logger = LoggerFactory.getLogger(Hibernate...

    • springboot中使用hibernate读取mysql数据库数据为空。

      最近在使用springboot连接mysql数据库的时候,出现了能够控制台能打印SQL语句去不能查询出数据的异常。经过一番修改终于发现原因: 使用jpa连接mysql数据库的时候在映射类中的命名的问题,例如在User类中,对应...

    • MySQL之—— 使用Hibernate连接MySQL数据库,MySQL连接超时断开的问题

      最近让人头疼的一个问题,就是服务器在不确定的时间点会出现关于数据库连接的Exception,大致的Exception如下: org.hibernate.util.JDBCExceptionReporter - SQL Error:0, SQLState: 08S01 org.hibernate.util....

    • Spring+ hibernate 注解 执行了save() 方法,但mysql数据库没显示数据

      @Transactional 在service 的实现类加上事务注解 然后才有了最后一句打印出来 前面数据库没有数据,没有这句话“insert into----”出现

    • Mysql数据库一次查询过程

      磁盘IO的 查询的优化

    • Java工作笔记-使用Hibernate连接mysql数据库并进行增、删、改、查!

      查询数据 修改数据库记录 删除数据库记录   环境要求 导入好Hibernate相关jar包, 并且对每一个表都生成了POJO类!   增加数据库记录 表结构如下:   这里使用Hibernate生成的POJO类如下: ...

    • 用eclipse写hibernate连接MySQL数据库案例

      1.在MySQL中创建一个user表包含id, username,password三个属性。id设为自动增长,其余两个为varchar(20)。 2.javabean user.java代码如下: package habernateOne; public class User { @Override p...

    • hibernate 对mysql方言_详解在Hibernate中配置数据库方言的作用和好处以及各种数据库的方言连接...

      Hibernate底层依然使用SQL语句来执行数据库操作,...举例来说,我们在MySQL数据库里进行分页查询,只需使用limit关键字就可以了;而标准SQL并不支持limit关键字,例如Oracle则需要使用行内视图的方式来进行分页。...

    • Sturts2整合Hibernate连接MySQL数据库

      一个整合Sturts2Hibernate连接MySQL数据库的小实例,能够连接MySQL实现数据库插入,查询,删除更新等操作

    • mysql hibernate如何向数据库表插入数据_插入hibernate数据库

      Hibernate连接DB2的问题(已解决)折腾半个月了,这个问题一直...在Mysql里使用一切正常,现在决定使用DB2数据库,理论上讲只要在DB2里建一个空数据库,然后修改hibernate.p...文章青夜之衫2017-12-06969浏览量Hiber...

    • 如何搭建Hibernate与MySQL数据库的连接

      hibernate为用户提供了封装好的类和方法,可直接在dao层中对数据库进行curd操作,不必再进行jdbc的代码实现, 也不需要再写SQL语句,hibernate的底层代码实现就是jdbc。 orm思想 orm(object relational mapping),...

    • 各种数据库查询前几条数据的方法

      sql在不同数据库查询前几条数据 关键字: sql 前几条结果  sql在不同数据库查询前几条数据  1. ORACLE   SELECT * FROM TABLE1 WHERE ROWNUM&amp;lt;=N    select * from stu_info where rownum&amp;lt;=10 ...

    • SpringBoot+hibernate+mysql的数据访问

      Hibernate是数据访问解决技术绝对霸主,使用O/R映射(Object-Relation Mapping)技术实现数据访问,O/R映射即将领域模型类和数据库的表进行映射,通过程序操作对象而实现数据表操作的能力,让数据访问操作无须关注...

    • SpringBoot+Hibernate+MySQL实现数据操作

      这篇文章介绍SpringBoot+Hibernate+MySQL实现数据操作,要实现这一部分功能首先得安装数据库MysQL。然后通过接口访问浏览器增删改查。 一、MySQL下载和安装 下载地址: ...

    • SpringBoot中连接MYSQL数据库,并使用JPA进行数据库的相关操作

      今天给大家介绍一下如何SpringBoot中连接Mysql数据库,并使用JPA进行数据库的相关操作。 想学习分布式、微服务、JVM、多线程、架构、java、python的童鞋,千万不要扫码,否则后果自负~ 步骤一:在pom.xml文件中...

    • 解决hibernate向mysql数据库传值中文乱码问题

      解决hibernate向mysql数据库传值中文乱码问题最近在完成老师的大作业,是写一个考试系统,需要往数据库存值。 在最开始的时候遇到了一些小问题,想记录一下,并分享一下自己的解决方案。一、最开始是将数据库中的...

    • Hibernate结合MySQL数据库生成数据表失败分析

      作为一个成熟的ORM框架,Hibernate对不同的数据库的支持可以说非常完美,但是在生成数据库的过程中还是会遇到各种各样的问题,今天在做数据表映射的时候,发现无法生成数据表,具体的开发环境如下:

    • springboot+hibernate+mysql简单例子

      简单的springboot的学习项目实例,使用了hibernate连接mysql数据库,进行简单的插入和查询操作,项目中已经包含依赖的jar包和数据库脚本,只需要创建配置的数据库并使用数据库脚本建立表即可。

    • 解决hibernate向mysql插入中文乱码

      1、首先需要修改mysql数据库的配置文件my.ini,此文件放在mysql根目录下。在此文件下查找default-character-set属性,并将其值更改为utf8(注意:不是utf-8,也要注意大小写),这里需要将default-character-set属性...

    Global site tag (gtag.js) - Google Analytics