2.angular指令

初级使用可以查看视频
参考手册
注意

  • 像ng-class,ng-value,ng-href等这些,很多都可以直接用class=“{{}}” 原生写,为啥还出这些指令,是因为原生的比如刚一进页面就先出现表达式了,浏览器走到这里的时候才去解析,给用户的体验不好

ng-app

  • angular只对这个标签以内的起作用,要不就直接原生解析
  • 告诉angular核心它管理当前标签所包含的整个区域,有自动创建$rootScope(根作用域对象),如果是可以ng-app = “*” 就是模块名 ,就是那个.module('')

ng-controller=“*”,

  • 新创建一个新的作用域,然后自动new构造函数就是.controller里面名字,(name, [ s c o p e , f u n c t i o n ( scope, function( scope,function(scope) {}]),
  • 用数组的原因,是这个$scope不可以变名字,但是压缩后的代码一般都会形参变成a,b,c,d这种,所以用数组这种传,
  • 可以使用as用来面向对象,其实就是相当于new的实例可以使用原型链上的方法或属性,面向对象

ng-repeat:

遍历,里面可以用$index, $first(第一项), $middle(除了第一和最后), $last(最后一项), $odd, $even / ng-repeat-start ng-repeat-end 可以用来嵌套
先来个完整的:后面只是使用的例子

ng-init 初始化数据 ng-init=“username=‘zjap’”, 一般也不会用,但是比如嵌套循环的时候可能会用到

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .active1 {
            background: red
        }
        .active2 {
            background: green
        }
    </style>
</head>
<body ng-app="myApp" ng-controller="Aaa">
    <ul>
        <!-- 隔行换色 -->
        <li ng-repeat="data in dataList" class="{{$odd? 'active1': 'active2'}}">{{data}}{{$odd}}</li>
    </ul>

    <table border="1">
      <!-- 这种相当于嵌套的<template v-for似的,ng-show让其隐藏要不可能影响合并> -->
        <tr ng-show="false" ng-repeat-start="data in twoTableLitst track by $index" ng-init="outIndex=$index"></tr>
          <tr ng-repeat="chil in data.children track by $index" ng-init="inIndex=$index">
            <td ng-if="inIndex == 0" rowspan="{{data.children.length}}">{{ data.name }}</td>
            <td>{{ chil }}</td>
          </tr>
        <tr ng-show="false" ng-repeat-end></tr>
    </table>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.8.2/angular.min.js"></script>
    <script>
        var m1 = angular.module('myApp', [])
        m1.controller('Aaa', ['$scope', function($scope) {
            $scope.dataList = ['aaa', 'bbb', 'ccc', 'ddd']
            $scope.twoTableLitst = [
                {name: 'aaa', children: ['11', '22']},
                {name: 'bbb', children: ['11', '22']},
            ]
        }])
    </script>
</body>
</html>
<body ng-app="myApp" ng-controller="Aaa as a1">
    <span>{{a1.text}}</span>
    <script src="./public/angular.js"></script>
    <script> 
        var m1 = angular.module('myApp', [])
        m1.controller('Aaa', ['$scope', FnAaa])
        function FnAaa($scope) {
        }
        FnAaa.prototype.text="woshi"
    </script>
</body>

ng-class:动态class

ng-style: 动态style

ng-href href

ng-src

ng-attr-**这个基本其他所有的属性都可以使用,因为不可能原生的都有对应的ng-属性,所以咱们就是所有属性都可以用这个eg:title

ng-disabled --$interval 不可点击

ng-readonly 只读

ng-checked 複選框选中

ng-value 输入框等的值

也可以用value=“{{}}”,但是这个体验不好,用户可能先在页面看到{{}},后期才能看到内容,所以推荐ng-value

<body ng-app="myApp" ng-controller="Aaa">
    <span ng-class="{active: IsDisabled}" ng-style="{color: 'yellow'}">{{ text }}</span>
    <span ng-style="ngStyle">{{ text }}</span>
    <span ng-class="ngClass">{{ text }}</span>
    <a ng-href="{{ngHerf}}" ng-attr-title="{{ text }}">qubaidu</a>
    <input type="button" ng-value="text" ng-disabled="IsDisabled">
    <input type="text" ng-value="text" ng-readonly="IsDisabled">
    <input type="checkbox" ng-checked="IsDisabled">
    <script src="./public/angular.js"></script>
    <script> 
        var m1 = angular.module('myApp', [])
        m1.controller('Aaa', ['$scope', '$interval', function($scope, $interval) {
            // setInterval --$scope.apply()
            let iNow = 5
            $scope.text = iNow + '秒'
            $scope.IsDisabled = true
            $scope.ngStyle={
                background: 'yellow',
                color: 'red'
            }
            $scope.ngClass = {
                active: true
            }
            $scope.ngHerf = "http://www.baidu.com"
            const timer = $interval(function() {
                iNow--
                $scope.text = iNow + '秒'
                if (iNow === 0) {
                    $interval.cancel(timer)
                    $scope.IsDisabled = false
                }
            }, 1000)
        }])
    </script>
</body>

ng-bind

解决{{}}闪屏问题,因为{{}} 当时浏览器不知道,到下面看到angular,再上去解析这种就会闪屏,跟ng-value似的

ng-cloak

这个就是比如用户就想用{{}}不想用ng-bind,但是想让{{}}解析出来才展示,平常时候就是display:none

ng-bind-template

这个就是比如标签中内容多个{{}},肯定用ng-bind不合适,所以就使用这个

ng-bind-html

这个就是解析成html,但是因为这个功能不常用,所以angular就设置成一个插件形式,后期需要按照模块引入就行,从这里查:https://www.bootcdn.cn/angular.js/,下面代码其实是有问题的,可能是引入的库不对,后面研究,但是写法基本是这种

ng-non-bindable // 就比如说想让{{}}展示出来,不去解析

<body ng-app="myApp" ng-controller="Aaa">
    <span ng-bind="text"></span>
    <span ng-cloak>{{ text }}</span>
    <span ng-bind-template="{{ text }}, {{text}}"></span>
    <div ng-bind-html="htmlstr"></div>
    <span ng-non-bindable>{{ text }}</span>
    <script src="./public/angular.js"></script>
    <script src="https://cdn.staticfile.org/angular.js/1.5.0-beta.0/angular-sanitize.min.js"></script>
    <script>
        // alert('1')
        var m1 = angular.module('myApp', ['ngSanitize'])
        m1.controller('Aaa', ['$scope', function($scope) {
            $scope.text = 'nihao'
            $scope.htmlstr = '<h1>1111</h1>'
        }])
    </script>
</body>

ng-show,ng-hide 显示隐藏,就是css的disable的切换

ng-if dom元素显示

ng-switch

ng-open 应用于details,默认是展开还是隐藏

<body ng-app="myApp" ng-controller="Aaa">
    <input type="button" value="点击" ng-click="checkButton()">
    <span v-if="isShow">展示</span>
    <div ng-switch on="lalal">
        <p ng-switch-when="1">我是1</p>
        <p ng-switch-when="2">我是2</p>
        <p ng-switch-default>我是其他</p>
    </div>

    <details ng-open="isShow">
        <summary>我是总体</summary>
        <p>我是介绍</p>
    </details>
    <script src="./public/angular.js"></script>
    <script> 
        var m1 = angular.module('myApp', [])
        m1.controller('Aaa', ['$scope', function($scope) {
            $scope.isShow = true
            $scope.lalal = 1
            $scope.checkButton = function() {
                $scope.isShow = !$scope.isShow
                $scope.lalal++
            }
        }])
    </script>
</body>

ng-model: 跟v-model似的,双向数据绑定,但是如果比如想不时实的去更改可以使用ng-model-options和updateOn去配置

ng-include 可以引入新的html,这个在这个上面写也是报错,目前不知道到为啥

—我知道为啥了,需要放到服务器上,不是本地浏览器打开

<body ng-app="myApp" ng-controller="Aaa">
    <!-- 但是不起作用,不知道为啥 -->
    <div ng-include="'moni.html'"></div>
    <!-- 不时实,失去焦点才变 -->
    <input type="text" ng-model="text" ng-model-options="{updateOn: 'blur'}">
    <span>{{text}}</span>
    <script src="./public/angular.js"></script>
    <script> 
        var m1 = angular.module('myApp', [])
        m1.controller('Aaa', ['$scope', function($scope) {
            $scope.text = "我是开始"
        }])
    </script>
</body>
</html>

事件

ng-mouseenter,ng-mouseleave 移入移出

ng-click/dbclick 点击

ng-selected //下拉菜单选中

ng-change // input change事件

ng-copy ng-cut ng-paste 输入框复制,j剪切,粘贴操作

其他原生事件都可以用ng-事件名

标签指令

<a> 普通的a标签会点击刷新页面有默认行为,angluar重新封装了下,没有默认行为了

select

-- ng-options

form

-- novalidate
<body>
    <div ng-app="myApp" ng-controller="Aaa">
        <!-- 默认行为点击 -->
        <a href="">{{myColor}}</a>
        <!-- myColor是color对象,color.name是展示的 -->
        <select ng-options="color.name for color in colors" ng-model="myColor"></select>
        <!-- 如果不写novalidate会有默认表单样式,比如说输入不是email,就会有红色边框,这没模拟出来 -->
        <form novalidate>
            <input type="email">
        </form>
    </div>
    <a href="">aaaaaaaaaaaa</a>
    <script src="./public/angular.js"></script>
    <script> 
        var m1 = angular.module('myApp', [])
        m1.controller('Aaa', ['$scope', function($scope) {
            $scope.colors = [{name: 'red'}, {name: 'yellow'}]
            $scope.myColor = ''
        }])
    </script>
</body>

表单指令

这些结合表单验证更容易理解,看3文档

自定义指令

我理解的自定义指令就是你可以把功能或者组件单独写出来,以供后期复用,相当于vue的component组件

介绍

  • restrict

    • E : 标签形式 eg: <hello>
    • A : 属性形式 eg: <div hello />
    • C: class形式 eg <div class=“hello” />
    • M: 注释写法 eg: <-- directive:hello -->注释需要replace: true 可以组合使用
      一般会使用前两个也就是‘E’和‘A’,一般A是功能性的使用较多,E一般是模板替代形式跟vue中组件似的
  • replace

    • true : 里面内容直接替换外面标签,要不总在写的里面
  • template

  • templateUrl

  • scope

    • true 独立作用域,如果不写这个scope的话就会所有组件公用一套数据,在一个上面改,其他的都会变
    • {} 隔离作用域,不再跟外层作用于有任何瓜葛,独立作用域还会集成上面的Aaa里面数据,这个隔离就不会继承了,只能使用什么就传过来
      • @ 就是解析字符串
      • = 找变量
      • & 函數
  • link —(scope, element, attr,reController) (reController就是拿别的组件里面的属性值,下面讲),主要用于操作dom的,跟controller的区别自己感觉是controller是可以吧公共逻辑都放在里面,当如果集成另一个指令,想拿另一个指令的定义的变量就可以用link的reController么

  • controller --就写逻辑的地方

  • transclude 这个就感觉像插槽的感觉,比如指令里面嵌套指令

代码中使用

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body ng-app="myApp">
    <div class="nihao" ng-controller="Aaa">
        <my-hello my-id="div1" my-name="name" my-fn="show(num)"></my-hello>
        <my-hello my-id="div2" my-name="name" my-fn="show(num)"></my-hello>
    </div>
    <script src="./public/angular.js"></script>
    <script> 
        var m1 = angular.module('myApp', [])
        m1.controller('Aaa', ['$scope', function($scope) {
            $scope.name = 'zhaohui'
            $scope.show = function(num) {
                alert(num)
            }
            
        }])
        m1.directive('myHello', function() {
            return {
                restrict: 'AE',
                replace: true, // 替换标签
                template: '<div id="{{myId}}" ng-click="myFn({num: 123})">{{name}}</div>',
                // templateUrl: './moni.html' // 本地的会跨域需要运行在服务上
                // scope: true, // 独立作用域 就比如第二个<my-hello 写ng-init="name=lala" ,则第一个就是zhaohui, 第二个就是lala
                // scope: {}, // 隔离作用域,其实上面那种就不去找Aaa controller的变量name,就找自己controller的内容
                scope: {
                    myId: '@', // 就是解析字符串,就比如説是div1,div2
                    myName: '=', // 找变量,视频说是找Aaa controller的变量name,但是我渲染的是zhaohui1234221,后面具体看吧
                    myFn: '&' // 函數,这个找的就是Aaa controller的方法
                },
                controller: ['$scope', function($scope) {
                    // 共享数据
                    $scope.name = 'zhaohui1234221'
                }],
                link: function(scope, element, attr) {
                    console.log(scope, element, attr) // 自己作用域(比如自己的controller.name), 元素(里面div), 属性
                    element.css('color', 'red')
                }
            }
        })
    </script>
</body>
</html>

鼠标拖拽

my-drag true是拖拽虛綫框。false是拖拽块

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        .box {
            width: 200px;
            height: 200px;
            background-color: red;
            position: absolute;
            left: 10px;
            top: 10px;
        }
    </style>
</head>
<body ng-app="myApp">
    <div class="nihao">
        <div my-drag="true" class="box"></div>
    </div>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
    <script src="./public/angular.js"></script>
    <script> 
        var m1 = angular.module('myApp', [])
        
        m1.directive('myDrag', function() {
            return {
                restrict: 'A',
                link: function(scope, element, attr) {
                    console.log('attr', attr, attr.myDrag) // 这个true是字符串
                    attr.myDrag = angular.equals(attr.myDrag, 'true') // 把它变成真正boolean
                    var disX = 0
                    var disY = 0
                    element.on('mousedown', function(ev) {
                        var This = this
                        disX = ev.pageX - $(this).offset().left
                        disY = ev.pageY - $(this).offset().top
                        if (attr.myDrag) {
                            var $line = $('<div>')
                             $line.css({
                                width: $(this).outerWidth(),
                                height: $(this).outerHeight(),
                                position: 'absolute',
                                left:  $(this).offset().left,
                                top: $(this).offset().top,
                                border: '1px dotted gray'
                             })   
                             $('body').append($line)
                        }

                        $(document).on('mousemove', function(ev) {
                            if (attr.myDrag) {
                                $line.css({
                                    left: ev.pageX - disX,
                                    top: ev.pageY - disY,
                                })
                            } else (
                                $(This).css({
                                    left: ev.pageX - disX,
                                    top: ev.pageY - disY,
                                })
                            )
                        })
                        $(document).on('mouseup', function(ev) {
                            $(document).off()
                            if (attr.myDrag) {
                                $(This).css({
                                    left: $line.offset().left,
                                    top: $line.offset().top,
                                })
                                $line.remove()
                            }
                        })
                        return false
                    })
                    
                }
            }
        })
    </script>
</body>
</html>

指令之间交互 transclude ng-transclude

这个就感觉像插槽的感觉,比如指令里面嵌套指令
require – 这个引入某个指令,然后reController就可以拿到了
^ – 此指令往上级找比如这里的,如果不写就直接是从自己标签上找hello指令
? – 比如说在标签上没找到hello指令会报错,这个就是一个容错处理,找不到那打印reController就报错,加了?就可以是undefined

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body ng-app="myApp">
    <hello>
        <hi></hi>
    </hello>
    <script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.6.1/jquery.js"></script>
    <script src="./public/angular.js"></script>
    <script> 
        var m1 = angular.module('myApp', [])
        
        m1.directive('hello', function() {
            return {
                restrict: 'E',
                replace: true,
                transclude: true,
                controller: function($scope) {
                    this.lalala = '我我我我我'
                },
                template: '<div>你好我是hello<h1 ng-transclude><h1></div>' // ng-transclude这个跟插槽似的告诉在这里渲染,搭配transclude: true
            }
        })
        m1.directive('hi', function() {
            return {
                restrict: 'E',
                replace: true,
                require: '^hello', // 引入hello,^从父级找
                template: '<div>你好我是hi</div>',
                link: function(scope, element, attr, reController) {
                    console.log(reController.lalala) // 这里能找到的原因就是require的hello组件中controller的this上的值
                }
            }
        })
    </script>
</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值