angularjs总结整理

一、angular介绍

1、angular是Google公司提供的一套基于MVC结构的js开发工具,其核心功能就是对现有html编码以指令方式进行扩展,并使其通过使用元素声明的方式来构建动态内容。
2、为实现上述目的,angular利用 了两项技术点:双向绑定和依赖注入

二、适用范围

angular是构建一个MVC类结构的js库,建议在构建CRUD应用时使用它。对于图形编辑、游戏开发不建议使用。

三、控制器

1、控制器功能是管理页面的逻辑代码。任务就是操作$scope对象。
2、当ng-controller指令被添加到dom页面上时,angular通过构造函数生成实体对象时,$scope注入其中,$scope与页面元素进行数据绑定,实现数据从控制器到视图层。
3、控制器是纯 Javascript 构造函数,所以应该用首字母大写的驼峰命名法(HomePageCtrl, ShoppingCartCtrl, AdminPanelCtrl, 等等)。
4、使用 数组定义语法声明控制器,如下

function MyCtrl($scope) {}
var myModule = angular.module('myModule',[])
myModule.controller('MyCtrl',['$scope',MyCtrl])

5、使用 controller as 语法:

<div ng-controller="MainCtrl as main">
   {{ main.title }}
</div>
app.controller('MainCtrl', MainCtrl);
function MainCtrl () {
  this.title = 'Some title';
}

使用 controller as 主要的优点是:

  • 创建了一个“独立”的组件——绑定的属性不属于 $scope 原型链。
  • Scope值的改变会在你不注意的地方有影响。
  • 难以重构。
  • 语法上更接近于普通的 JavaScript 构造函数。
    请看: digging-into-angulars-controller-as-syntax
    6、不要在控制器中写业务逻辑,业务逻辑交给模型层的服务。
    // 这是把业务逻辑放在控制器的常见做法
angular.module('Store', [])
.controller('OrderCtrl', function ($scope) {
  $scope.items = [];
  $scope.addToOrder = function (item) {
    $scope.items.push(item);//-->控制器中的业务逻辑
  };
  $scope.removeFromOrder = function (item) {
    $scope.items.splice($scope.items.indexOf(item), 1);//-->控制器中的业务逻辑
  };
  $scope.totalPrice = function () {
    return $scope.items.reduce(function (memo, item) {
      return memo + (item.qty * item.price);//-->控制器中的业务逻辑
    }, 0);
  };
});

当你把业务逻辑交给模型层的服务,控制器看起来就会想这样:(关于 service-model 的实现,参看 'use services as your Model'):
// Order 在此作为一个 'model'

angular.module('Store', [])
.controller('OrderCtrl', function (Order) {
  $scope.items = Order.items;
  $scope.addToOrder = function (item) {
    Order.addToOrder(item);
  };
  $scope.removeFromOrder = function (item) {
    Order.removeFromOrder(item);
  };
  $scope.totalPrice = function () {
    return Order.total();
  };
});

为什么控制器不应该包含业务逻辑和应用状态?
①控制器会在每个视图中被实例化,在视图被销毁时也要同时销毁
②控制器是不可重用的——它与视图有耦合
③Controllers are not meant to be injected
7、有内嵌的控制器时使用 "内嵌作用域" ( controllerAs 语法):

app.js
module.config(function ($routeProvider) {
  $routeProvider
    .when('/route', {
      templateUrl: 'partials/template.html',
      controller: 'HomeCtrl',
      controllerAs: 'home'
    });
});
HomeCtrl
function HomeCtrl() {
  this.bindingValue = 42;
}
template.html
<div ng-bind="home.bindingValue"></div>

四 模板

1、避免在模板中使用复杂的表达式。
2、当需要动态设置 的 src 时使用ng-src而非 src中嵌套 {{}} 的模板。href同理。
3、通过 ng-style 指令配合对象式参数和scope变量来动态设置元素样式,而不是将 scope变量作为字符串通过 {{ }} 用于 style 属性。

<script>
...
$scope.divStyle = {
  width: 200,
  position: 'relative'
};
...
</script>
<div ng-style="divStyle">hello world</div>;

4、添加元素样式

$scope.a=true;
$scope.b=false;
<div ng-class="{'red':a,'blue':b}"></div>
$scope.blnfocus=true;
<div ng-class="{true:'red',false:'blue'}[blnfocus]"></div>

列表中还有ng-class-oddng-class-even
简单例子:

<li     ng-repeat="stu in data"
    ng-click="li_click($index)"
    ng-class-odd="odd"
    ng-class-even="even"
    ng-class="{focus:$index===focus}"
>
    <span>{{stu.name}}</span>
    <span>{{$first?'是':'否'}}</span>
    <span>{{$last?'是':'否'}}</span>
</li>
$scope.li_click = function (i) {
    $scope.focus = i;
}

css中需要加入.odd .even .focus
5、元素显示隐藏ng-show ng-hide ng-switch(ng-switch-when ng-switch-default)

五 过滤器

1、orderby

<li  ng-repeat="stu in data|orderBy:'-score'|limitTo:3">

按分数降序排列,只显示3条
2、匹配方式过滤filter
{{数据|filter:匹配项}}
匹配项可以是字符串、对象和函数

<li  ng-repeat="stu in data|filter:findscore">
$scope.findscore = function (e){
  return e.score>85 && e.score<90;
}

3、在需要格式化数据时将格式化逻辑封装成 过滤器 并将其声明为依赖
自定义过滤器

<li  ng-repeat="stu in data|young:0">
module.filter('young',function(){
    return function (e,type) {
        var _out = [];
        var _sex = type ? "男":"女";
        for (var i = 0;i<e.length;i++) {
            if (e[i].age > 22 && e[i].age<28 && e[i].sex == _sex)
    _out.push(e[i]);    
        }
        return _out;
    }
})

controller中注入自定义的filter

function MyCtrl($scope, young){
}
module.controller('MyCtrl', MyCtrl);

4、重要应用
①表头排序

<li >
    <span ng-click="title='name';desc=!=desc">姓名</span>
    <span ng-click="title='score';desc=!=desc">分数</span>
</li>
<li     ng-repeat="stu in data">
    <span>{{stu.name}}</span>
    <span>{{stu.score}}</span>
</li>
$score.title = 'name'
$score.desc = 0

②字符查找

<input  type="text" ng-model="key">
<li     ng-repeat="stu in data | filter:{name:key}">
    <span>{{stu.name}}</span>
    <span>{{stu.score}}</span>
</li>

六 作用域

作用域是控制器与视图的桥梁,也是指令与视图的桥梁
1、提供$watch方面监听数据模型变化(ng-model双向绑定)

<input  type="text" ng-model="key">
$scope.$watch('key',function(){
    //...
})

2、子级可继承父级作用域全部属性和方法
同级不可以相互访问属性和方法
3、两种方式实现作用域通信
①在作用域间创建一个单例的服务
②事件:只能父子相传,同级接受不到

$broadcasted(eventname,data) 父到子
$emitted(eventname,data) 子到父
$on(eventname,function(event,data)){
//
}

在作用域监听传播来的事件并获取相应的数据

七 依赖注入

1、当在代码中声明了依赖关系后,Angular通过injector注入器将所依赖的对象进行"注入"操作
2、config函数为定义的模板对象注入依赖的各种服务,除了用于注册控制器的controllerProvider服务外,还有provide服务,它包含了几个重要方法provider,factory,service,value
3、依赖注入标记
①标记式注入
调用$injector属性来完成,字符型数组,一定要按注入方式的顺序来

var MyCtrl = function($scope,$window,$show);
MyCtrl.$inject=[$scope,$window,$show]

②行内式注入
将一个字符型数组作为对象参数,最后一个是函数体,其余是注入对象中的服务名,它们顺序与函数体参数一一对应

module.controller('MyCtrl',[$scope,$window,function($scope,$window){
    // ...
}])

4、依赖注入应用场景
①构建控制器:上述标记式注入
②工厂方法:类似'config','factory','directive','filter'等构造性质的方法

八 angular服务

1、内置服务:$scope,$http,$window,$location
2、创建angular服务,除了调用$provide服务,还可以直接调用模块中的factory、service、constantvalue等方法来创建。
3、把业务逻辑封装到服务中,把业务逻辑抽象为服务作为你的model。例如:

//Order is the 'model'
angular.module('Store')
.factory('Order', function () {
    var add = function (item) {
      this.items.push (item);
    };
    var remove = function (item) {
      if (this.items.indexOf(item) > -1) {
        this.items.splice(this.items.indexOf(item), 1);
      }
    };
    var total = function () {
      return this.items.reduce(function (memo, item) {
        return memo + (item.qty * item.price);
      }, 0);
    };
    return {
      items: [],
      addToOrder: add,
      removeFromOrder: remove,
      totalPrice: total
    };
});

如果需要例子展现如何在控制器中使用服务,请参考 'Avoid writing business logic inside controllers'。

九 使用promise而非回调

1、处理异步编程的模式,可以有效解决回调的繁琐,以一种同步的方式去处理业务逻辑。
2、想要在angular中创建promise对象,必须在模板中注入$q服务,并先调用defer方法创建一个延期对象。

var defer = $q.defer()

defer是一个延期对象,它包含3个方法notify、resolve、reject和promise对象
promise对象有一个then方法

promise.then(successCallback,errorCallback,notifyCallback)

3、实例

module.factory("async",function($q,$http){
    var defer = $q.defer();
    $http.get('data/asycn')
    .success(function(data){
        defer.resolve(data);
    })
    .error(function(reason){
        defer.reject(reason) ; 
   })
    return defer.promise;
})
.controller("MyCtrl",function($scope,async){
    var promise = async;
    promise.then(function(resp){
        $scope.result = "成功"+resp;
    },function(n){
        $scope.result = "失败"+n;
   })
})

十 注意事项

1、调用element方法控制dom元素

angular.element(document.getElementById("control")).append(newhtml)

2、setTimeout无效,调用$timeout服务
在angular中,大部分操作之后的效果都是由$apply方法自动在页面完成,若调用非angular中方法,系统不会调用$apply方法在页面中同步操作结果
3、{{}}闪烁问题
使用ng-bind ng-cloak

<div ng-cloak>{{message}}</div>

4、使用track by排序ng-repeat中的数据
5、释放多余的$watch检测函数,再次调用$watch就可释放它的检测功能

$scope.stopWatch = function() {
    contentWatch();
}
var contentWatch = $scope.$watch('content',function(newVal,oldVal){
    if(newVal===oldVal){return;}
   $scope.count++;
})

6、ng-ifng-model值无效

<div ng-if="!a">
    <input type="checkbox" ng-model="$parent.b">
</div>

参考:https://github.com/mgechev/angularjs-style-guide/blob/master/README-zh-cn.md
angularjs实战

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,233评论 4 360
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,013评论 1 291
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,030评论 0 241
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,827评论 0 204
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,221评论 3 286
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,542评论 1 216
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,814评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,513评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,225评论 1 241
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,497评论 2 244
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 31,998评论 1 258
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,342评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 32,986评论 3 235
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,055评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,812评论 0 194
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,560评论 2 271
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,461评论 2 266

推荐阅读更多精彩内容