Web前端学习笔记——AngularJS入门

目录

什么是 AngularJS

为什么使用 AngularJS

AngularJS 的核心特性

相关链接

Angular 上手

安装 Angular

简单示例

案例解析

使用总结

Angular 基础概念

MVC 思想

模型

控制器

 

视图模型($scope)

表达式(Expression)

对比 JavaScript 表达式

单向数据绑定

双向数据绑定

Angular 指令系统(Directive)

指令属性小提示

ng-app 指令

ng-bind指令

ng-bind-html指令

ng-repeat 指令

ng-class 指令

ng-show/ng-hide 指令

 ng-cloak指令

ng-link/ng-src 指令

 ng-switch指令

其他常用指令

自定义指令

todomvc-app-template案例


什么是 AngularJS

  • 一款非常优秀的前端高级 JS 框架
  • 最早由 Misko Hevery 等人创建
  • 2009 年被 Google 公式收购,用于其多款产品
  • 目前有一个全职的开发团队继续开发和维护这个库
  • 有了这一类框架就可以轻松构建 SPA 应用程序
  • 轻松构建 SPA(单一页面应用程序)
  • 单一页面应用程序:
    • 只有一个页面(整个应用的一个载体)
    • 内容全部是由AJAX方式呈现出啦的
  • 其核心就是通过指令扩展了 HTML,通过表达式绑定数据到 HTML。

为什么使用 AngularJS

  • 更少的代码,实现更强劲的功能
  • 将一些以前在后台开发中使用的思想带入前端开发
  • 带领当前市面上的框架走向模式化或者架构化

以前我们是这样的:

以后将会是这样的:

传统方式实现加法运算

Angular实现加法运算

传统方式实现数据列表呈现

Angular实现数据列表呈现

AngularJS 的核心特性

  • MVC
  • 模块化
  • 自动化双向数据绑定
  • 指令系统

相关链接

  • http://www.apjs.net/
  • http://www.angularjs.cn/
  • http://docs.angularjs.cn/api
  • https://material.angularjs.org
  • http://angular-ui.github.io/

Angular 上手

安装 Angular

  • 下载 Angular.js 的包
    • https://github.com/angular/angular.js/releases
  • 使用 CDN 上的 Angular.js
    • http://apps.bdimg.com/libs/angular.js/1.4.9/angular.min.js
  • 使用 Bower 安装 bash bower install angular
  • 使用 NPM 安装 bash npm install angular
  • 每种方式安装包,本质都是将angular的库下载到当前文件夹中

简单示例

Hello world

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>第一个AngularJS示例</title>
</head>

<body>
  <div ng-app ng-init="name='zhangsan'">
    <p>在输入框中尝试输入:</p>
    <p>姓名:
      <input type="text" ng-model="name">
    </p>
    <p>{{name}}</p>
  </div>
  <script src="../bower_components/angular/angular.js"></script>
</body>

</html>

案例解析

  • 当网页加载完毕,AngularJS 自动开始执行;
  • HTML 页面中 ng-xxx 的属性称之为指令(Directive);
  • ng-app 指令告诉 AngularJS,<div> 元素是 AngularJS 应用程序管理的边界;
  • ng-model 指令把文本框的值绑定到变量 name 上;
  • {{ name }} 表达式就是把应用程序变量 name 绑定到某个段落的 innerHTML。

使用总结

  • Angular 最大程度的减少了页面上的 DOM 操作;
  • 让 JavaScript 中专注业务逻辑的代码;
  • 通过简单的指令结合页面结构与逻辑数据;
  • 通过自定义指令实现组件化编程;
  • 代码结构更合理;
  • 维护成本更低;
  • Angular 解放了传统 JavaScript 中频繁的 DOM 操作
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Angular Hello world</title>
</head>
<!--
所有需要ng管理的代码必须被包裹在一个有ng-app指令的元素中
ng-app是ng的入口,表示当前元素的所有指令都会被angular管理(对每一个指令进行分析和操作)
-->
<body>
  <div ng-app ng-init="user.name='world'">
    <h1>使用NG实现双边数据绑定</h1>
    <input type="text"
      placeholder="请输入你的姓名"
      ng-model="user.name">
    <p>hello <strong>{{user.name}}</strong></p>
  </div>
  <script src="bower_components/angular/angular.js"></script>
</body>

</html>

 

Angular 基础概念

MVC 思想

什么是 MVC 思想

  • MVC 是一种应用程序的开发思想,不是设计模式
  • 主要目的是为了解决应用程序展示结构,业务逻辑之间的紧耦合关系
  • 使应用程序的组成分为三个部件,每个部件有自己明确的职责,相互之间没有依赖
  • 将应用程序的组成划分为三个部分:Model View Controller
  • 控制器的作用就是初始化模型用的;
  • 模型就是用于存储数据的
  • 视图用于展现数据

模型

  • AngularJS很重要的一个特性就是实现模块化编程,我们可以通过以下方式创建一个模块,对页面进行功能业务上的划分

// 创建一个名字叫MyApp的模块,第二个参数指的是该模块依赖那些模块
var myApp = angular.module("MyApp", []);
  • 也可以将重复使用的指令或过滤器之类的做成模块便于复用
  • 注意必须指定第二个参数,否则变成找到已经定义的模块
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Angular 模块</title>
</head>

<body>
  <div ng-app="myApp" ng-controller="DemoController">
    <h1>使用NG实现双边数据绑定</h1>
    <input type="text" placeholder="请输入你的姓名" ng-model="user.name">
    <p>hello <strong>{{user.name}}</strong></p>
    <input type="button" ng-click="show()">
  </div>
  <script src="bower_components/angular/angular.js"></script>
  <script>
    // 注册模块 通过module函数,
    // 第一个参数是这个模块的名字
    // !!! 第二个参数是这个模块所依赖的模块, 如果不依赖任何模块也必须传递第二个参数,如果没有传递第二个参数,angular.module就不是创建一个模块
    // angular.module 返回 刚刚创建的模块对象
   var app=  angular.module('myApp',[]);
    // app.controller 方法用于创建一个控制器,所创建的控制器属于myApp模块
    // app.controller('DemoCtrl');
    // 控制器函数的参数中有一个$scope
    // angular.module('myApp').controller('DemoController', function($scope) {
    //   // 当控制器执行时会自动执行的函数
    //   $scope.user = {};
    //   $scope.user.name = '张三';
    //   // $scope不仅仅可以往视图中暴露数据,还可以暴露行为
    //   $scope.show = function() {
    //     console.log($scope.user);
    //   };
    // });
  </script>
</body>

</html>

控制器

  • 调度逻辑的集合

angular.module('OneApp', [])
    .controller('HelloController', [
        '$scope',
        function($scope) {
            $scope.p = {
                name: 'zhangsan'
            };
        }
    ]);
  • 控制器的三种主要职责:
  1. –为应用中的模型设置初始状态
  2. –通过$scope对象把数据模型或函数行为暴露给视图
  3. –监视模型的变化,做出相应的动作
// 监视购物车内容变化,计算最新结果
$scope.$watch(‘totalCart’, calculateDiscount);
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Angular Controller</title>
</head>

<body ng-app="myModule" ng-controller="HelloController">
  <script src="bower_components/angular/angular.js"></script>
  <script>
    // 由于控制器是必须出现在某个模块下的,想创建一个控制器必须先创建模块
    var module = angular.module('myModule', []); // 返回的就是模块对象

    // angular在执行控制器函数时,
    // 会根据参数的名字($scope)去自动的注入对象
    // 根据参数名称传递对应对象,所以必须要写正确的参数名称
    // module.controller('HelloController', function($scope) {
    //   console.log($scope);
    // });
    //
    // 由于压缩代码会改变参数名称,注册控制的标准方式就是通过第二个参数传递数组的方式(数组的成员最后一个就是原本的控制器函数,前面的成员都是需要注入的对象名称)
    module.controller('HelloController', ['$scope','$http', function(a,b) {
      console.log(a);
    }]);
  </script>
</body>

</html>
<!DOCTYPE html>
<html lang="en" ng-app="HelloApp">

<head>
  <meta charset="utf-8">
</head>

<body>
  <table border="1" ng-controller="WorldController">
    <tr>
      <td>用户名</td>
      <td>
        <input type="text" ng-model="user.username">
      </td>
    </tr>
    <tr>
      <td>密码</td>
      <td>
        <input type="password" ng-model="user.password">
      </td>
    </tr>
    <tr>
      <td></td>
      <td>
        <input type="button" ng-click="login()" value="登陆">
      </td>
    </tr>
    <tr>
      <td></td>
      <td>{{message}}</td>
    </tr>
  </table>
  <script src="bower_components/angular/angular.js"></script>
  <script>
    // 创建一个模块
    var app = angular.module('HelloApp', []);
    // 为这个模块创建一个控制器
    app.controller('WorldController', ['$scope', function($scope) {

      // 数据
      $scope.user = {
        username: '',
        password: ''
      };
      $scope.demo = '';

      // 行为数据
      $scope.login = function() {
        // 因为数据的变化时双向的同步,所以界面上的值变化会同步到$scope.user上
        console.log($scope.user);
      };


      // 请输入用户名  输入格式不合法
      $scope.message = '请输入用户名';
      // $scope.message取决于$scope.user

      // 官方的API中提供了一个$scope.$watch方法,
      $scope.$watch('user.username', function(now, old) {
        // 当user.username发生变化时触发这个函数
        // console.log('now is ' + now);
        // console.log('old is ' + old);
        if (now) {
          if (now.length < 7) {
            $scope.message = '输入格式不合法';
          } else {
            $scope.message = '';
          }
        } else {
          $scope.message = '请输入用户名';
        }
      });

      // angular 基本不用操作DOM,如果必要,可以使用angular提供的jqlite
      //
      // angular.element('body')
    }]);
  </script>
</body>

</html>

 

视图模型($scope)

  • 视图和控制器之间的桥梁
  • 用于在视图和控制器之间传递数据
  • 利用$scope暴露数据模型(数据,行为)

表达式(Expression)

  • 作用:
  1. –使用 表达式 把数据绑定到 HTML。
  • 语法:
  1. –表达式写在双大括号内:{{ expression }}
  • 比较:
  1. –表达式作用类似于ng-bind指令
  2. –建议更多的使用指令
  • AngularJS表达式很像JavaScript表达式
  • 它们可以包含文字、运算符和变量
  • 如 {{ 5 + 5 }} 或 {{ firstName + ‘-’ + lastName }}
  • 数字  {{ 100 + 100 }}
  • 字符串  {{ 'hello' + 'angular' }}
  • 对象  {{ zhangsan.name }}
  • 数组  {{ students[10] }}
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Angular 表达式</title>
  <style>
    /* ng-cloak指令就是在NG执行完毕过后自动移除 */

    [ng-cloak],
    .ng-cloak {
      display: none;
    }
  </style>
</head>

<body ng-app class="ng-cloak">
  {{ true ? 'true':'false' }}
  <script src="bower_components/angular/angular.js"></script>
</body>

</html>

对比 JavaScript 表达式

  • 相同点:
  1. –AngularJS 表达式可以包含字母,操作符,变量。
  • 不同点:
  1. –AngularJS 表达式可以写在 HTML 中。
  2. –AngularJS 表达式不支持条件判断,循环及异常。
  3. –AngularJS 表达式支持过滤器。

单向数据绑定

•模型变化过后,自动同步到界面上;

•一般纯展示型的数据会用到单项数据绑定;

•使用表达式的方式都是单向的

双向数据绑定

•两个方向的数据自动同步:

•模型发生变化自动同步到视图上;

•视图上的数据发生变化过后自动同步到模型上;

Angular 指令系统(Directive)

  • AngularJS 有一套完整的、可扩展的、用来帮助 Web 应用开发的指令集
  • 在 DOM 编译期间,和 HTML 关联着的指令会被检测到,并且被执行
  • 在 AngularJS 中将前缀为 ng- 这种属性称之为指令,其作用就是为 DOM 元素调用方法、定义行为绑定数据等
  • 简单说:当一个 Angular 应用启动,Angular 就会遍历 DOM 树来解析 HTML,根据指令不同,完成不同操作

指令属性小提示

  • HTML5 允许扩展的(自制的)属性,以 data- 开头。
  • AngularJS 属性以 ng- 开头,但是您可以使用 data-ng- 来让网页对 HTML5 有效。
  • 二者效果相同。

ng-app 指令

  • ng-app指令用来标明一个AngularJS应用程序
  • 标记在一个AngularJS的作用范围的根对象上
  • 系统执行时会自动的执行根对象范围内的其他指令
  • 可以在同一个页面创建多个ng-app节点
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>ng-app 指令</title>
</head>

<body>
  <!-- angular找到第一个ng-app过后就不会再找 -->
  <div ng-app="myApp1" ng-controller="App1Controller">
    <input type="button" value="按钮1" ng-click="do1()">
  </div>
  <div ng-app="myApp2" ng-controller="App2Controller">
    <input type="button" value="按钮2" ng-click="do2()">
  </div>
  <script src="bower_components/angular/angular.js"></script>
  <script>
    /**
     * myApp1 Module
     *
     * Description
     */
    var myApp1 = angular.module('myApp1', []);
    myApp1.controller('App1Controller', ['$scope', function($scope) {
      $scope.do1 = function() {
        console.log(11111);
      };
    }]);

    var myApp2 = angular.module('myApp2', []);
    myApp2.controller('App2Controller', ['$scope', function($scope) {
      $scope.do2 = function() {
        console.log(22222);
      };
    }]);
    // 手动的让第二个div被myApp2管理
    angular.bootstrap(document.querySelector('[ng-app="myApp2"]'),['myApp2']);
  </script>
</body>

</html>

 

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>ng-app 指令</title>
</head>

<body ng-app="myApp">
  <!-- angular找到第一个ng-app过后就不会再找 -->
  <div ng-controller="App1Controller">
    <input type="button" value="按钮1" ng-click="do1()">
  </div>
  <div ng-controller="App2Controller">
    <input type="button" value="按钮2" ng-click="do2()">
  </div>
  <script src="bower_components/angular/angular.js"></script>
  <script>
    // 零件1
    var myApp1 = angular.module('myApp1', []);
    myApp1.controller('App1Controller', ['$scope', function($scope) {
      $scope.do1 = function() {
        console.log(11111);
      };
    }]);
    // 零件2
    var myApp2 = angular.module('myApp2', []);
    myApp2.controller('App2Controller', ['$scope', function($scope) {
      $scope.do2 = function() {
        console.log(22222);
      };
    }]);

    /**
     * myApp Module
     *
     * Description
     */
    angular.module('myApp', ['myApp1', 'myApp2']);
  </script>
</body>

</html>

ng-bind指令

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>ng-bind 指令</title>
</head>
<body ng-app ng-init="username='<h1>shit</h1>'">
  <!-- <strong>{{username}}</strong> -->
  <!-- ng-bind指令在绑定的值包含HTML时会转义,为了安全(跨站脚本攻击) -->
  <strong ng-bind="username"></strong>
  <script src="bower_components/angular/angular.js"></script>
</body>
</html>

ng-bind-html指令

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>ng-bind-html 指令</title>
</head>

<body ng-app="myApp" ng-init="username='<h1>shit</h1>'">
  <!-- <strong>{{username}}</strong> -->
  <!-- ng-bind指令在绑定的值包含HTML时会转义,为了安全(跨站脚本攻击) -->
  <strong ng-bind-html="username"></strong>
  <script src="bower_components/angular/angular.js"></script>
  <script src="bower_components/angular-sanitize/angular-sanitize.js"></script>
  <script>
    // 使用自定义的模块才可以依赖别的包里面定义模块,angular定义的默认模块没有依赖任何
    angular.module('myApp', ['ngSanitize']);
  </script>
</body>

</html>

ng-repeat 指令

  • ng-repeat指令用来编译一个数组重复创建当前元素,如
<ul class="messages">
    <li ng-repeat="item in messages track by $index">
        {{item}}
    </li>
</ul>

 

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>ng-repeat 指令</title>
</head>

<body ng-app="myApp">

<ul ng-controller="ListController">
  <!-- ng-repeat 会遍历数组中每一个元素,分别创建li -->
  <li ng-repeat="item in xiaoheishenghuo" data-id="{{item.id}}">
    <span>{{$first?'开始':''}}</span>
    <strong>{{item.name}}</strong>
    &nbsp;&nbsp;&nbsp;&nbsp;
    <span>{{item.age}}</span>
    <span>{{$last?'没有了':''}}</span>
  </li>
</ul>

  <script src="bower_components/angular/angular.js"></script>
  <script>
    angular.module('myApp', [])
      .controller('ListController', ['$scope', function($scope) {


        $scope.xiaoheishenghuo = [];

        for (var i = 1; i < 10; i++) {
          $scope.xiaoheishenghuo[$scope.xiaoheishenghuo.length] = {
            id: i,
            name: '赵小黑的小' + i,
            age: 20 + i
          };
        }


      }]);
  </script>
</body>

</html>

ng-class 指令

  • ng-class指令可以设置一个键值对,用于决定是否添加一个特定的类名,键为class名,值为bool类型表示是否添加该类名
<ul class="messages">
    <li ng-repeat="item in messages track by $index" ng-class="{red:item.read}">
        {{item.content}}
    </li>
</ul>

 

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>ng-repeat 指令</title>
  <style>
    .red {
      color: red;
    }

    .green {
      color: green;
    }
  </style>
</head>

<body ng-app="myApp">
  <ul ng-controller="ListController">
    <!-- class="{{$even?'red':'green'}}" -->
    <!-- ng-class会根据当前设置对象的属性和属性值决定是否添加特定类名 -->
    <li ng-repeat="item in xiaoheishenghuo" ng-class="{red:$even,green:$odd}" data-id="{{item.id}}">
      <strong>{{item.name}}</strong> &nbsp;&nbsp;&nbsp;&nbsp;
      <span>{{item.age}}</span>
    </li>
  </ul>
  <script src="bower_components/angular/angular.js"></script>
  <script>
    angular.module('myApp', [])
      .controller('ListController', ['$scope', function($scope) {


        $scope.xiaoheishenghuo = [];

        for (var i = 1; i < 10; i++) {
          $scope.xiaoheishenghuo[$scope.xiaoheishenghuo.length] = {
            id: i,
            name: '赵小黑的小' + i,
            age: 20 + i
          };
        }


      }]);
  </script>
</body>

</html>
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>ng-repeat 指令</title>
  <style>
    .red {
      background-color: red;
    }

    .green {
      background-color: green;
    }

    #box {
      height: 200px;
      width: 200px;
      transition:background-color 1s ease;
    }
  </style>
</head>

<body ng-app>
  <select ng-model="style">
    <option value="red">红色</option>
    <option value="green">绿色</option>
  </select>
  <!-- <div id="box" ng-class="style"></div> -->
  <div id="box" ng-class="{red:style=='red', green:style=='green'}"></div>
  <script src="bower_components/angular/angular.js"></script>
</body>

</html>

 

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>ng-repeat 指令</title>
  <style>
    .red {
      color: red;
    }

    .green {
      color: green;
    }
  </style>
</head>

<body ng-app="myApp">
  <input type="text" ng-model="lastname">
  <ul ng-controller="ListController">
    <li ng-repeat="name in students track by $id($index)" ng-class="{red:lastname!=''&&name.startsWith(lastname)}">{{name}}</li>
  </ul>
  <script src="bower_components/angular/angular.js"></script>
  <script>
    angular.module('myApp', [])
      .controller('ListController', ['$scope', function($scope) {


        $scope.students = ['胡shit', '赵四', '网商务', '李三', '李三', '李三'];


      }]);
  </script>
</body>

</html>

ng-show/ng-hide 指令

  • ng-show/ng-hide指令会根据属性值去确定是否展示当前元素,例如ng-show=false则不会展示该元素
<ul class="messages">
    <li ng-repeat="item in messages track by $index" ng-show="item.read">
        {{item.content}}
    </li>
</ul>
<!DOCTYPE html>
<html lang="en" ng-app="myApp">

<head>
  <meta charset="UTF-8">
  <title>ng-class 指令</title>
  <style>
    .tips {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      background-color: rgba(100, 100, 100, .5);
      font-size: 40px;
      line-height: 100vh;
      text-align: center;
    }
  </style>
</head>

<body ng-controller="ListController">
  <div>
    aaaaaaaaaaaaaa
  </div>
  <!-- ng-show 决定是否显示 ng-hide 是否隐藏 ng-if 是否存在 -->
  <div class="tips" ng-if="loading">
    loading...
  </div>
  <script src="bower_components/angular/angular.js"></script>
  <script>
    angular.module('myApp', [])
      .controller('ListController', ['$scope', '$timeout', function($scope, $timeout) {
        $scope.loading = true;

        $timeout(function() {
          $scope.loading = false;

          $timeout(function() {
            $scope.loading = true;
          }, 3000);

        }, 3000);
      }]);
  </script>
</body>

</html>

 

 ng-cloak指令

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>ng-cloak 指令</title>
  <!-- <style>
    [ng\:cloak],
    [ng-cloak],
    [data-ng-cloak],
    [x-ng-cloak],
    .ng-cloak,
    .x-ng-cloak,
    .ng-hide:not(.ng-hide-animate) {
      display: none !important;
    }

    ng\:form {
      display: block;
    }

    .ng-animate-shim {
      visibility: hidden;
    }

    .ng-anchor {
      position: absolute;
    }
  </style> -->
  <script src="bower_components/angular/angular.js"></script>
</head>

<body ng-app ng-cloak>
  <span>{{'hello angular'}}</span>
</body>

</html>
  • ng-if是指是否存在DOM元素

ng-link/ng-src 指令

  • ng-link/ng-src指令用于解决当链接类型的数据绑定时造成的加载BUG,如
<!-- 浏览器在解析HTML时会去请求{{item.url}}文件 -->
<img src="{{item.url}}">
<!-- 可以使用ng-src解决该问题 -->
<img ng-src="{{item.url}}">
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>ng-src</title>
  <script src="bower_components/angular/angular.js"></script>
</head>

<body ng-app ng-init="imgUrl='22.png'" ng-cloak>
  <img ng-src="{{imgUrl}}" alt="">

  <a ng-href="{{imgUrl}}">跳转到图片</a>
</body>

</html>

 ng-switch指令

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>ng-switch 指令</title>
</head>
<body ng-app>
  <select ng-model="selected">
    <option value="1">1</option>
    <option value="2">2</option>
    <option value="3">3</option>
  </select>
  <div ng-switch="selected">
    <div ng-switch-when="1">
      你选择的是1
    </div>
    <div ng-switch-when="2">
      你选择的是2
    </div>
    <div ng-switch-when="3">
      你选择的是3
    </div>
    <div ng-switch-default>
      你什么都没选
    </div>
  </div>

  <script src="bower_components/angular/angular.js"></script>
</body>
</html>

其他常用指令

  • ng-model
  • ng-class
  • ng-show/ng-hide/ng-if
  • ng-click
  • ng-link/ng-src
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>ng-xxx 其他指令</title>
</head>

<body ng-app>
  <p>
    <input type="checkbox" ng-model="checked">全选/取消全选</p>
  <ul>
    <!-- ng-checked 和 ng-selected 只会做数据到视图的同步,不会做视图到数据的同步 -->
    <li>选项01
      <input type="checkbox" ng-checked="checked">
    </li>
    <li>选项02
      <input type="checkbox" ng-checked="checked">
    </li>
    <li>选项03
      <input type="checkbox" ng-checked="checked">
    </li>
    <li>选项04
      <input type="checkbox" ng-checked="checked">
    </li>
    <li>选项05
      <input type="checkbox" ng-checked="checked">
    </li>
  </ul>
  <script src="bower_components/angular/angular.js"></script>
</body>

</html>

自定义指令

  • AngularJS中可以通过代码自定义指令:
myModule.directive('hello', function() {
    return {
        restrict: 'E',
        template: '<h1>Hello world</h1>',
        replace: true
    };
});
myApp.directive("ngHover", function() {
    return function(scope, element, attrs) {
        element.bind("mouseenter", function() {
            element.css("background", "yellow");
        });
        element.bind("mouseleave", function() {
            element.css("background", "none");
        });
    }
});
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css">
</head>

<body ng-app="demoApp">
  <!-- <itcastButton></itcastButton> -->
  <!-- <itcast-button></itcast-button> -->
  <!-- <div itcastButton></div> -->
  <btn-primary></btn-primary>
  <btn-danger></btn-danger>
  <script src="bower_components/angular/angular.js"></script>
  <script>a
    var demoApp = angular.module('demoApp', []);

    // 第一个参数是指令的名字,第二个参数任然应该使用一个数组,数组的最后一个元素是一个函数
    // 定义指令的名字,应该使用驼峰命名法
    demoApp.directive('itcastButton', [function() {
      // 该函数应该返回一个指令对象
      return {
        template:'<input type="button" value="itcast" class="btn btn-lg btn-primary btn-block" />'
      };
    }]);


    // demoApp.directive('btnPrimary', [function() {
    //   return {
    //     template:'<input type="button" value="itcast" class="btn btn-primary" />'
    //   };
    // }]);

    // demoApp.directive('btnDanger', [function() {
    //   return {
    //     template:'<input type="button" value="itcast" class="btn btn-danger" />'
    //   };
    // }]);

    // demoApp.directive('btnSuccess', [function() {
    //   return {
    //     template:'<input type="button" value="itcast" class="btn btn-success" />'
    //   };
    // }]);

    demoApp.controller('DemoController', ['$scope', function($scope) {
      // $scope.xxxx=xxx;
      // $scope.do=function() {

      // };
      // $scope.$watch('',function(now,old) {

      // });
    }]);
  </script>
</body>

</html>
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css">
</head>

<body ng-app="demoApp">
  <!-- <btn>itcast</btn> -->
  <div breadcrumb></div>
  <breadcrumb data=""></breadcrumb>
  <script src="bower_components/angular/angular.js"></script>
  <script>
    var demoApp = angular.module('demoApp', []);


    demoApp.directive('breadcrumb', [function() {
      // Runs during compile
      return {
        // 指定当前指令的类型什么样的
        // restrict: 'EA',
        // // E = Element, A = Attribute, C = Class, M = Comment
        // template: '', // 模版字符串
        templateUrl: 'tmpls/breadcrumb.html',
        replace: true,
        // transclude: true,
      };
    }]);

    // demoApp.directive('btn', [function() {
    //   return{
    //     scope:{
    //       primary:'@',
    //       lg:'@',
    //       block:'@',
    //     },
    //     template:'<button class="btn {{primary==\'true\'?\'btn-primary\':\'\'}}">button</button>'
    //   }
    // }]);

    // demoApp.directive('btn', [function() {
    //   return {
    //     // 指令对象的transclude必须设置为true才可以在模版中使用ng-transclude指令
    //     transclude: true,
    //     replace: true, // 替换指令在HTML中绑定的元素
    //     template: '<button class="btn btn-primary btn-lg" ng-transclude></button>'
    //   };
    // }]);
  </script>
</body>

</html>
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>封装一个面包屑导航</title>
  <link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.css">
</head>

<body ng-app="myApp" ng-controller="DemoController">
  <breadcrumb data="{{pathData1}}"></breadcrumb>
  <breadcrumb data="{{pathData2}}"></breadcrumb>
  <script src="bower_components/angular/angular.js"></script>
  <script>
    var myApp = angular.module('myApp', []);

    myApp.controller('DemoController', ['$scope', function($scope) {
      $scope.pathData1 = {
        home: '#',
        itcast: '#',
        itheima: '#',
        bbs: '#'
      };
      $scope.pathData2 = {
        home: '#',
        library: '#',
        data: '#'
      };
    }]);

    // 定义一个面包屑导航指令
    myApp.directive('breadcrumb', [function() {
      // 返回指令对象
      return {
        scope: {},
        templateUrl: 'tmpls/breadcrumb.html',
        replace: true,
        link: function(scope, element, attributes) {
          scope.data = JSON.parse(attributes.data);
          // console.log(scope.data);
        }
      };
    }]);
  </script>
</body>

</html>

todomvc-app-template案例

<!doctype html>
<html lang="en">
	<head>
		<meta charset="utf-8">
		<meta name="viewport" content="width=device-width, initial-scale=1">
		<title>Template • TodoMVC</title>
		<link rel="stylesheet" href="node_modules/todomvc-app-css/index.css">
		<!-- CSS overrides - remove if you don't need it -->
		<link rel="stylesheet" href="css/app.css">
	</head>
	<body ng-app="MyTodoMvc">
		<section class="todoapp" ng-controller="MainController">
			<header class="header">
				<h1>todos</h1>
				<form ng-submit="add()">
					<input class="new-todo" placeholder="What needs to be done?" ng-model="text" autofocus>
				</form>
			</header>
			<section class="main">
				<input class="toggle-all" type="checkbox" ng-click="toggleAll()">
				<label for="toggle-all">Mark all as complete</label>
				<ul class="todo-list">
					<li ng-repeat="todo in todos" ng-class="{completed:todo.completed,editing:todo.id===currentEditingId}" data-id="{{todo.id}}">
						<div class="view">
							<input class="toggle" type="checkbox" ng-model="todo.completed">
							<label ng-dblclick="editing(todo.id)">{{todo.text}}</label>
							<button class="destroy" ng-click="remove(todo.id)"></button>
						</div>
						<form ng-submit="save()">
							<input class="edit" ng-model="todo.text" ng-blur="save()">
						</form>
					</li>
				</ul>
			</section>
			<!-- This footer should hidden by default and shown when there are todos -->
			<footer class="footer">
				<!-- This should be `0 items left` by default -->
				<span class="todo-count"><strong>{{todos.length}}</strong> item left</span>
				<!-- Remove this if you don't implement routing -->
				<ul class="filters">
					<li>
						<a class="selected" href="#/">All</a>
					</li>
					<li>
						<a href="#/active">Active</a>
					</li>
					<li>
						<a href="#/completed">Completed</a>
					</li>
				</ul>
				<!-- Hidden if no completed items are left ↓ -->
				<button class="clear-completed" ng-click="clear()" ng-show="existCompleted()">Clear completed</button>
			</footer>
		</section>
		<footer class="info">
			<p>Double-click to edit a todo</p>
			<!-- Remove the below line ↓ -->
			<p>Template by <a href="http://sindresorhus.com">Sindre Sorhus</a></p>
			<!-- Change this out with your name and url ↓ -->
			<p>Created by <a href="http://todomvc.com">you</a></p>
			<p>Part of <a href="http://todomvc.com">TodoMVC</a></p>
		</footer>
		<!-- Scripts here. Don't remove ↓ -->
		<script src="node_modules/angular/angular.js"></script>
		<script src="js/app.js"></script>
	</body>
</html>
<--!app.js-->
(function(angular) {
  'use strict';

  /**
   * MyTodoMvc Module
   *
   * 应用程序的主要的模块
   */
  var myApp = angular.module('MyTodoMvc', []);

  // 注册一个主要的控制器
  myApp.controller('MainController', ['$scope', function($scope) {
    // [1,2,3,4,5]
    function getId() {
      var id = Math.random(); // 1 2
      for (var i = 0; i < $scope.todos.length; i++) {
        if ($scope.todos[i].id === id) {
          id = getId();
          break;
        }
      }
      return id;
    }

    // 文本框需要一个模型
    $scope.text = '';

    // 任务列表也需要一个
    // 每一个任务的结构 { id: 1, text: '学习', completed: true }
    $scope.todos = [{
      id: 0.123,
      text: '学习',
      completed: false
    }, {
      id: 0.22,
      text: '睡觉',
      completed: false
    }, {
      id: 0.232,
      text: '打豆豆',
      completed: true
    }, ];

    // 添加todo
    $scope.add = function() {
    	if(!$scope.text){
    		return;
    	}
      $scope.todos.push({
        // 自动增长?
        id: getId(),
        // 由于$scope.text是双向绑定的,add同时肯定可以同他拿到界面上的输入
        text: $scope.text,
        completed: false
      });
      // 清空文本框
      $scope.text = '';
    };


    // 处理删除
    $scope.remove = function(id) {
      // 删除谁
      for (var i = 0; i < $scope.todos.length; i++) {
        if ($scope.todos[i].id === id) {
          $scope.todos.splice(i, 1);
          break;
        }
      }
      // $scope.todos
    };

    // 清空已完成
    $scope.clear = function() {
      var result = [];
      for (var i = 0; i < $scope.todos.length; i++) {
        if (!$scope.todos[i].completed) {
          result.push($scope.todos[i]);
        }
      }
      $scope.todos = result;
    };

    // 是否有已经完成的
    $scope.existCompleted = function() {
      // 该函数一定要有返回值
      for (var i = 0; i < $scope.todos.length; i++) {
        if ($scope.todos[i].completed) {
          return true;
        }
      }
      return false;
    };

    // 当前编辑哪个元素
    $scope.currentEditingId = -1;
    $scope.editing = function(id) {
      $scope.currentEditingId = id;
    };
    $scope.save = function() {
      $scope.currentEditingId = -1;
    };

    // $scope.checkall = false;
    // $scope.$watch('checkall', function(now, old) {
    //   for (var i = 0; i < $scope.todos.length; i++) {
    //     $scope.todos[i].completed = now;
    //   }
    // });

    var now = true;
    $scope.toggleAll = function() {
      for (var i = 0; i < $scope.todos.length; i++) {
        $scope.todos[i].completed = now;
      }
      now = !now;
    }

  }]);

})(angular);

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值