JavaScript

AngularJS指令

2017-04-28  本文已影响0人  LiuliuZhang

HTML5 允许扩展的(自制的)属性,以 data- 开头。
AngularJS 属性以 ng- 开头,但是您可以使用 data-ng- 来让网页对 HTML5 有效。
二者效果相同。
ng-app:
标记在一个AngularJS的作用范围,标记范围尽可能小,解析快。可以在同一个页面创建多个ng-app节点,但不推荐。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>

需要手动的让第二个div被myApp2管理angular.bootstrap(document.querySelector('[ng-app="myApp2"]'),['myApp2']);,第一个参数传哪个DOM元素,可以用document.querySelector来选择,第二个参选传哪个处理模块

    var myApp2 = angular.module('myApp2', []);
    myApp2.controller('App2Controller', ['$scope', function($scope) {
      $scope.do2 = function() {
        console.log(22222);
      };

如有需要两个模块管理,一般定义好myApp1和myApp2后,通过angular.module('myApp', ['myApp1', 'myApp2']);组合成myApp,然后在上一级中指定myApp<body ng-app="myApp">

ng-bind:
ng-bind 将作用域中的值绑定到innerHTML上,效果比表达式更友好,没有闪过表达式原型的情况。ng-bind指令在绑定的值包含HTML时会转义,为了安全(跨站脚本攻击),如下代码会输出<h1>shit</h1>

<body ng-app ng-init="username='<h1>shit</h1>'">
  <strong ng-bind="username"></strong>

若要输出不转义的语义HTML,可以用ng-bind-html指令<strong ng-bind-html="username"></strong>除此之外,需要安装angular-sanitize,可以用npm install angular-sanitize --save来安装,在页面中<script src="node_modules/angular-sanitize/angular-sanitize.js"></script>引入,使用自定义的模块才可以依赖别的包里面定义模块,angular定义的默认模块没有依赖任何angular.module('myApp', ['ngSanitize']);
跨站脚本攻击示意如下,在文章评论处插入跨站脚本,服务器会存储下来,后面用户在加载页面时,会执行这段script脚本(参考www.wooyun.org

ng-repeat:
对初始的data数组赋值可以用下面方法

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

ng-repeat主要应用于数组,如下遍历数组中每一个元素,分别创建li。item in data 循环取出data数组中的每一行为item

<ul ng-controller="ListController">
  <li ng-repeat="item in data" data-id="{{item.id}}">
    <span>{{$first?'开始':''}}</span>
    <strong>{{item.name}}</strong>
        
    <span>{{item.age}}</span>
    <span>{{$last?'没有了':''}}</span>
  </li>
</ul>

可以在scope中查看每个li的属性,自带了一些是否首尾项奇偶等属性


ng-class
定义好style后,通过<li ng-repeat="item in xiaoheishenghuo" ng-class="{red:$even,green:$odd}" data-id="{{item.id}}">来使隔行换色。red:$even表示当even属性返回为true,会添加red这个class

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

select下拉框选项,首先在model中建立style,当选中red时,给style赋值red通过ng-class="{red:style=='red', green:style=='green'}来根据style的值决定用哪个class

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

给数组赋值有重名$scope.students = ['胡shit', '赵四', '网商务', '李三', '李三', '李三'];,使用<li ng-repeat="name in students">{{name}}</li>会报错,应该加上index name in students track by $index
使用startWith来判断是填入的姓时是红色,刚开始时,lastname为undfined,下面的都不是以undfined开头,但是当填入数据后再删除,lastname为空字符串,所有的都是以空字符开头,就都是红色。可以加上{red:lastname!=''&&name.startsWith(lastname)}来加上非空判断

  <input type="text" ng-model="lastname">
  <ul ng-controller="ListController">
    <li ng-repeat="name in students track by $index" ng-class="{red:name.startsWith(lastname)}">{{name}}</li>
  </ul>

Loading用法<body ng-controller="ListController" ng-class="{loading:loading}">加入loading,在代码中先设为true,3s后设为false移除loading面板

    angular.module('myApp', [])
      .controller('ListController', ['$scope', '$timeout', function($scope, $timeout) {
        $scope.loading = true;
        $timeout(function() {
          $scope.loading = false;
        }, 3000);
      }]);

样式代码如下

  <style>
    body.loading > .tips {
      display: block;
    }

    .tips {
      display: none;
      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>

其他指令
show / hide
ng-show 决定是否显示 ng-hide 是否隐藏 ng-if 是否存在DOM元素
ng-show=false相当于添加了ng-hide的style class,里面样式display: none;配合上面例子的loading变量,ng-show="loading"ng-hide="!loading"ng-if中的表达式为false时,这个元素会被remove掉

src / href
ng-link/ng-src指令用于解决当链接类型的数据绑定时造成的加载BUG,如下若使用src="{{imgUrl}}",Angular没加载完会先直接请求这个地址,此时地址无效,控制台会有请求错误,等Angular加载后再请求到实际地址。图片将从一个无效图片转为实际图片。使用ng-cloak可以解决闪过的无效图片问题,但控制台还是会有错误。因此Angular封装了ng-src和ng-href

<body ng-app ng-init="imgUrl='22.png'" ng-cloak>
  ![]({{imgUrl}})
  <a ng-href="{{imgUrl}}">跳转到图片</a>
</body>

ng-switch
根据当前的值显示或隐藏对应部分,配合 ng-switch-when, ng-switch-default 使用

  我喜欢的网站
  <select ng-model="myVar">
    <option value="google">www.google.com</option>
    <option value="taobao">www.taobao.com</option>
  </select>
  <hr>
  <div ng-switch="myVar">
    <div ng-switch-when="google">
      <h1>Google</h1>
      <p>欢迎访问Google</p>
    </div>
    <div ng-switch-when="taobao">
      <h1>淘宝</h1>
      <p>欢迎访问淘宝</p>
    </div>
    <div ng-switch-default>
      <h1>切换</h1>
      <p>选择不同选项显示对应的值。</p>
    </div>
  </div>

ng-checked
ng-mode绑定到checked,ng-checked 和 ng-selected也绑定,但不会双向绑定。 只会做数据到视图的同步,不会做视图到数据的同步

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

  </ul>

自定义指令
定义指令的名字,应该使用驼峰命名法。自定义指令与定义控制器类似,第一个参数指令名,第二个是数组。<itcast-button></itcast-button>加载组件。把重复的封装好,让我们使用更方便。例如自定义指令实现Bootstrap的Button样式

    demoApp.directive('itcastButton', [function() {
      // 该函数应该返回一个指令对象
      return {
        template:'<input type="button" value="itcast" class="btn btn-lg btn-primary btn-block" />'
      };
    }]);

页面上<btn primary="true" lg block>itcast</btn>
自定义属性,@会取标签上对应的属性值,primary="true"会取消样式

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

<btn>itcast</btn>我们要实现将btn元素替换成bootstrap的button样式,首先要使用ng-transclude指令,通过replace: true 替换指令在HTML中绑定的<btn>元素

    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>'
      };
    }]);

参考
https://angular-ui.github.io/bootstrap/
https://material.angularjs.org/latest/demo/bottomSheet

上一篇 下一篇

猜你喜欢

热点阅读