欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

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

程序员文章站 2022-05-08 08:38:21
...

目录

什么是 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

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

以前我们是这样的:

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

以后将会是这样的:

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

传统方式实现加法运算

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

Angular实现加法运算

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

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

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

Angular实现数据列表呈现

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

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);

 

相关标签: WEB前端