AngularJS 学习笔记

本文发布于 6 年前,部分内容可能已经失去参考价值。

1.1 四大特性

MVC

<!doctype html>
<html ng-app>
<body>
    <div ng-controller="HelloAngular">
        <p>{{greeting.text}}, Angular</p>
    </div>
    <script src="js/angular-1.3.0.js"></script>
    <script>
        function HelloAngular($scope) {
            $scope.greeting = {
                text: 'Hello'
            };
        }
    </script>
</body>
</html>

模块化与依赖注入

<!doctype html>
<html ng-app="app">
<body>
    <div ng-controller="HelloAngular">
        <p>{{greeting.text}}, Angular</p>
    </div>
    <script src="js/angular-1.3.0.js"></script>
    <script>
        var myModule = angular.module("app", []);

        myModule.controller("HelloAngular", ['$scope',
            function($scope) {
                $scope.greeting = {
                    text: 'Hello'
                };
            }
        ]);
    </script>
</body>
</html>

双向数据绑定

<!doctype html>
<html ng-app>
<body>
    <input ng-model="greeting.text" />
    <p>{{greeting.text}},AngularJS</p>
    <script src="js/angular-1.3.0.js"></script>
</body>
</html>

指令

<!doctype html>
<html ng-app="app">
<body>
    <hello></hello>
    <script src="js/angular-1.3.0.js"></script>
    <script>
        var myModule = angular.module("app", []);
        myModule.directive("hello", function () {
            return {
                restrict: 'E',
                template: '<div>Hi everyone!</div>',
                replace: true
            }
        });
    </script>
</body>
</html>


1.2 开发环境

node.js
JS 运行环境
Bower插件管理(相当于 NuGet)
Grunt代码混淆、合并工具
Sublime代码编辑器(小巧),Zen Coding 快速编写 HTML/CSS 代码
WebStorm代码编辑器(强大)
git 小乌龟版本管理


2.1 MVC

Controller 使用要点:

  • 不要复用 Controller

  • 不要操作 DOM

  • 不要做数据格式化,ng 有表单控件

  • 不要做数据过滤,ng 有 $filter


$scope 作用域

<!doctype html>
<html ng-app>
<head>
    <style>
        .show-scope-demo .ng-scope, .show-scope-demo .ng-scope { border: 1px solid red; margin: 3px; }
    </style>
</head>
<body>
    <div class="show-scope-demo">
        <div ng-controller="GreetCtrl">
            Hello {{name}}!
        </div>
        <div ng-controller="ListCtrl">
            <ol>
                <li ng-repeat="name in names">
                    {{name}} from {{department}}
                </li>
            </ol>
        </div>
    </div>
    <script src="js/angular-1.3.0.js"></script>
    <script>
        function GreetCtrl($scope, $rootScope) {
            $scope.name = 'World';
            // 在根作用域定义了 department,在 ListCtrl 控制器中也能用
            $rootScope.department = 'Angular';
        }

        function ListCtrl($scope) {
            $scope.names = ['Igor', 'Misko', 'Vojta'];
        }
    </script>
</body>
</html>
<!doctype html>
<html ng-app>
<head>
    <style>
        .show-scope-demo .ng-scope, .show-scope-demo .ng-scope { border: 1px solid red; margin: 3px; }
    </style>
</head>
<body>
    <div ng-controller="EventController">
        Root scope
        <tt>MyEvent</tt> count: {{count}}
        <ul>
            <li ng-repeat="i in [1]" ng-controller="EventController">
                <button ng-click="$emit('MyEvent')">
                    $emit('MyEvent')
                </button>
                <button ng-click="$broadcast('MyEvent')">
                    $broadcast('MyEvent')
                </button>
                <br>
                Middle scope
                <tt>MyEvent</tt> count: {{count}}
                <ul>
                    <li ng-repeat="item in [1, 2]" ng-controller="EventController">
                        Leaf scope
                        <tt>MyEvent</tt> count: {{count}}
                    </li>
                </ul>
            </li>
        </ul>
    </div>
    <script src="js/angular-1.3.0.js"></script>
    <script>
        function EventController($scope) {
            $scope.count = 0;
            $scope.$on('MyEvent', function () {
                $scope.count++;
            });
        }

    </script>
</body>
</html>

$emit:向上传播

$broadcast:向下传播

ng-repeat="i in [1, 2]":循环固定项

$scope 是一个树形结构,与 DOM 平行

子 $scope 对象会继承父 $scope 上的属性和方法

每个 Angular 应用只有一个根 $scope,一般位于 ng-app 上

$scope 可以传播事件,类似 DOM 事件,可向上可向下

 

2.2 路由、模块、依赖注入

var bookStoreApp = angular.module('bookStoreApp', [
    'ngRoute', 'ngAnimate', 'bookStoreCtrls', 'bookStoreFilters',
    'bookStoreServices', 'bookStoreDirectives'
]);

bookStoreApp.config(function($routeProvider) {
    $routeProvider.when('/hello', {
        templateUrl: 'tpls/hello.html',
        controller: 'HelloCtrl'
    }).when('/list',{
    	templateUrl:'tpls/bookList.html',
    	controller:'BookListCtrl'
    }).otherwise({
        redirectTo: '/hello'
    })
});


2.3 双向数据绑定

绑定方式1:<p>{{greeting.text}}, Angular</p>

绑定方式2:<p><span ng-bind="greeting.text"></span>, Angular</p>

方式1 在加载 angular.js 之前会将 {{***}} 显示于界面,因此在 index.html 页面建议用方式2,通过模板加载的页面上的绑定可以使用方式1。

<!doctype html>
<html ng-app="UserInfoModule">

<head>
    <meta charset="utf-8">
    <link rel="stylesheet" href="css/bootstrap-3.0.0/css/bootstrap.css">
</head>

<body>
    <div class="panel panel-primary">
        <div class="panel-heading">
            <div class="panel-title">双向数据绑定</div>
        </div>
        <div class="panel-body">
            <div class="row">
                <div class="col-md-12">
                    <form class="form-horizontal" role="form" ng-controller="UserInfoCtrl">
                        <div class="form-group">
                            <label class="col-md-2 control-label">
                                邮箱:
                            </label>
                            <div class="col-md-10">
                                <input type="email" class="form-control" placeholder="推荐使用126邮箱" ng-model="userInfo.email">
                            </div>
                        </div>
                        <div class="form-group">
                            <label class="col-md-2 control-label">
                                密码:
                            </label>
                            <div class="col-md-10">
                                <input type="password" class="form-control" placeholder="只能是数字、字母、下划线" ng-model="userInfo.password">
                            </div>
                        </div>
                        <div class="form-group">
                            <div class="col-md-offset-2 col-md-10">
                                <div class="checkbox">
                                    <label>
                                        <input type="checkbox" ng-model="userInfo.autoLogin">自动登录
                                    </label>
                                </div>
                            </div>
                        </div>
                        <div class="form-group">
                            <div class="col-md-offset-2 col-md-10">
                                <button class="btn btn-default" ng-click="getFormData()">获取Form表单的值</button>
                                <button class="btn btn-default" ng-click="setFormData()">设置Form表单的值</button>
                                <button class="btn btn-default" ng-click="resetForm()">重置表单</button>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
    <script src="js/angular-1.3.0.js"></script>
    <script>
        var userInfoModule = angular.module('UserInfoModule', []);
        userInfoModule.controller('UserInfoCtrl', ['$scope',
            function ($scope) {
                $scope.userInfo = {
                    email: "253445528@qq.com",
                    password: "253445528",
                    autoLogin: true
                };
                $scope.getFormData = function () {
                    console.log($scope.userInfo);
                };
                $scope.setFormData = function () {
                    $scope.userInfo = {
                        email: 'damoqiongqiu@126.com',
                        password: 'damoqiongqiu',
                        autoLogin: false
                    }
                };
                $scope.resetForm = function () {
                    $scope.userInfo = {
                        email: "253445528@qq.com",
                        password: "253445528",
                        autoLogin: true
                    };
                }
            }
        ]);
    </script>
</body>
</html>

注意 ng-click 的用法。

ng-class 用法:

ng-class='{bg-danger: isError, bg-success: isSuccess}'

表示当 isError 为 true 时应用 bg-danger 样式,当 isSuccess 为 true 时应用 bg-success 样式。

ng-show / ng-hide 用法:

ng-show='isShow'

表示当 isShow 为 true 时显示,否则隐藏。


2.4 指令(Directive)重要!

路由

Angular 自带的 angular.route.js 不能实现嵌套路由,推荐使用 UI-Router,方便将页面分割成多个 ui-view 实现局部更新。

angular.module("app", []).directive("directiveName", function () {
    return {
        //通过设置项来定义 
    };
});

设置项:

restrict: 'AEMC', // A 属性(默认),E 元素,M 注释,C 样式

template: '<div>xxx</div>', // 替代的 HTML

replace: true, // 替代

transclude: true, // 嵌套,需要 template 配合,例如:

templace: '<div>xxx <div ng-transclude></div></div>', // 原来指令标签中的内容会被放置于 ng-transclude 所在 div 中。

templaceUrl: 'xxx.html', // 使用独立 html 的模板内容

compile: function() { }, // 对模板自身进行转换

link: function() {}, // 操作 DOM、绑定事件监听器


可以在页面中使用 ui-sref 或控制器中 $state.go 来实现跳转(页面更新)

如何传递参数:

一个简单的示例:在一个文章列表页面和一个文章详情页面中实现跳转,需要传递参数文章 id

  1. 在路由配置 state 中加入:params: { "id": null }

  2. 在列表行中绑定 id,格式如:<a ui-sref="app.blog.item({id:row.id})"><span>Edit</span></a>

  3. 在详情页控制器中接收参数:$stateParams,即可用 $stateParams.id 来获取文章 id 值

  4. 如果需要同时更改地址栏 url,并且能够使用该 url 直接打开该文章,那么修改 state 中的 url 为 /item?id,体现为 #/app/blog/item?id=9,也可以用冒号 /item:id,体现为 #/app/blog/item9

参:URL Parameters


scope 的绑定策略:

@:把当前属性作为字符串传递。你还可以绑定来自外层 scope 的值,在属性值中插入 {{ }} 即可

=:与父 scope 中的属性进行双向绑定

&:传递一个来自父 scope 的函数,稍后调用

ERP 类型的系统必备 UI 组件:MiniUIExt JS

互联网/电商型系统必备 UI 组件:KISSY

其它常用组件:AngularUI


2.5 Service 与 Provider

使用 $http.get 获取 JSON 数据

<!doctype html>
<html ng-app="app">
<head>
    <meta charset="UTF-8">
    <script src="framework/1.3.0.14/angular.js"></script>
</head>
<body>
    <div ng-controller="LoadDataCtrl">
        <ul>
            <li ng-repeat="user in users">
                {{user.name}}
            </li>
        </ul>
    </div>
    <script>
        var app = angular.module("app", []);
        app.controller('LoadDataCtrl', ['$scope', '$http', function ($scope, $http) {
            $http({
                method: 'GET',
                url: 'data.json'
            }).success(function (data, status, headers, config) {
                console.log("success...");
                console.log(data);
                $scope.users = data;
            }).error(function (data, status, headers, config) {
                console.log("error...");
            })
        }]);
    </script>
</body>
</html>

data.json:

[
	{ "name": "a" },
	{ "name": "b" },
	{ "name": "c" }
]

自定义 Service

<!doctype html>
<html ng-app="app">
<head>
    <meta charset="UTF-8">
    <script src="framework/1.3.0.14/angular.js"></script>
</head>
<body>
    <div ng-controller="ServiceController">
        <label>用户名:</label>
        <input type="text" ng-model="username" placeholder="请输入用户名" />
        <ul ng-show="username">
            <li ng-repeat="user in users">
                {{user.name}}
            </li>
        </ul>
    </div>
    <script>
        var app = angular.module("app", []);

        app.factory('userListService', ['$http', function ($http) {
            var doRequest = function (username, path) {
                return $http({ method: 'GET', url: 'data.json' });
            };
            return {
                userList: function (username) {
                    return doRequest(username, 'userList');
                }
            }
        }]);

        app.controller('ServiceController', ['$scope', '$timeout', 'userListService', function ($scope, $timeout, userListService) {
            var timeout;
            $scope.$watch('username', function (newUserName) {
                if (newUserName) {
                    if (timeout) {
                        $timeout.cancel(timeout);
                    }
                    timeout = $timeout(function () {
                        userListService.userList(newUserName)
                            .success(function (data, status) {
                                $scope.users = data;
                            });
                    }, 350);
                }
            });
        }]);
    </script>
</body>
</html>

知识点:

$timeout 延时,防抖动

userListService 服务调用 $http 服务获取数据,返回一个对象

自定义 Service 命名不要以“$”开头,可以像内置 Service 一样注入的,注入时必须放在内置 Service 之后

Service 是单例的

Service 只要声明,不需要实例化

Service 在整个应用的生命周期中存在,可以用来共享数据


$filter

currency / date / filter / json / limitTo / lowercase / number / orderBy / uppercase

data 例:

{{ 1304375948024 | data }}

{{ 1304375948024 | data:"MM/dd/yyyy @ h:mma" }}

{{ 1304375948024 | data:"yyyy-MM-dd hh:mm:ss" }}

效果:

May 3, 2011

05/03/2011 @ 6:39AM

2011-05-03 06:39:08

自定义 filter:

<!doctype html>
<html ng-app="app">
<head>
    <meta charset="UTF-8">
    <script src="framework/1.3.0.14/angular.js"></script>
</head>
<body>
    {{'xoyozo'|filter1}}
    <script>
        var app = angular.module("app", []);
        app.filter('filter1', function () {
            return function (item) {
                return item + 'o(u_u)o';
            }
        });
    </script>
</body>
</html>

其它常用 Service:内置共 24 个

$compile 编译服务

$filter 数据格式化工具,内置了 8 个

$interval

$timeout

$locale

$location

$log

$parse

$http 封装了 ajax


2.6 综合实例 BookStore



xoyozo 7 年前
转载请注明出处
可能相关的内容