Angularjs 创建可复用组件实例代码


Posted in Javascript onOctober 09, 2016

AngularJS框架可以用Service和Directive降低开发复杂性。这个特性非常适合用于分离代码,创建可测试组件,然后将它们变成可重用组件。

Directive是一组独立的JavaScript、HTML和CSS,它们封装了一个特定的行为,它将成为将来创建的Web组件的组成部分,我们可以在各种应用中重用这些组件。在创建之后,我们可以直接通过一个HTML标签、自定义属性或CSS类、甚至可以是HTML注释,来执行一个Directive。

这一篇教程将介绍如何创建一个‘自定义步长选择' Directive,它可以作为一个可重用输入组件。本文不仅会介绍Directive的一般创建过程,还会介绍输入控件验证方法,以及如何使用ngModelController无缝整合任意表单,从而利用AngularJS表单的现有强大功能。

直接上代码:

html:

<!-- lang: html -->
<body ng-app="demo" ng-controller="DemoController">
  <form name="form" >
    Model value : <input type="text" size="3" ng-model="rating"><br>
    Min value: <input type="text" size="3" ng-model="minRating"><br>
    Max value: <input type="text" size="3"ng-model="maxRating"><br>
    Form has been modified : {{ form.$dirty }}<br>
    Form is valid : {{ form.$valid }}
    <hr><divmin="minRating"max="maxRating"ng-model="rating"rn-stepper></div></form></body>

js:

<!-- lang: js -->
angular.module(‘demo‘, [
  ‘revolunet.stepper‘
])

.controller(‘DemoController‘, function($scope) {
  $scope.rating = 42;   
  $scope.minRating = 40;
  $scope.maxRating = 50;
});

rn-stepper最简结构

<!-- lang: js -->
// we declare a module name for our projet, and its dependencies (none)
angular.module(‘revolunet.stepper‘, [])
// declare our naïve directive
.directive(‘rnStepper‘, function() {
  return {
    // can be used as attribute or element
    restrict: ‘AE‘,
    // which markup this directive generates
    template: ‘<button>-</button>‘ +
            ‘<div>0</div>‘ +
            ‘<button>+</button>‘
  };
});

现在directive rnStepper 已经有了一个简单的雏形了。

可以有如下两种试用方法:

<div rn-stepper> </div>
<rn-stepper> </rn-stepper>

demo: http://jsfiddle.net/revolunet/n4JHg/

添加内部动作

直接上代码:

<!-- lang: js -->
.directive(‘rnStepper‘, function() {
  return {
    restrict: ‘AE‘,

    // declare the directive scope as private (and empty)
    scope: {},

    // add behaviour to our buttons and use a variable value
    template:
        ‘<button ng-click="decrement()">-</button>‘ +
        ‘<div>{{value}}</div>‘ +
        ‘<button ng-click="increment()">+</button>‘,

    // this function is called on each rn-stepper instance initialisation
    // we just declare what we need in the above template
    link: function(scope, iElement, iAttrs) {
      scope.value = 0;
      scope.increment = function() {
        scope.value++;
      };
      scope.decrement = function() {
        scope.value--;
      };
    }
  };
});

我们在template中,分别给两个button添加了click事件响应,在link方法中实现了响应的方法。
这里的scope是一个private scope,其作用域仅限rnStepper这个directive。

demo: http://jsfiddle.net/revolunet/A92Aw/

与外部世界(外部作用域)的交互

直到上面为止,我们的rnStepper都是自己跟自己玩,并没有跟外部作用域进行一些交互。

下面我们将添加一个数据绑定,使rnStepper与外部世界建立联系。

直接上代码:

<!-- lang: js -->
scope: {
  value: ‘=ngModel‘
}

我们在scope中添加了一组键值对,这样,会自动建立内部变量value与外部属性ngModel的联系。
这里的=代表的意思是双向绑定(double data-binding)。

什么叫双向绑定?

即: 当value发生改变,那么ngModel也会发生改变,反之亦然。

在我们的这个demo中,看下面这行代码:

<!-- lang: js -->
<div rn-stepper ng-model="rating"></div>

这里的意思就是: directive rnStepper的内部变量value与外部scope中的rating建立了双向数据绑定。

demo: http://jsfiddle.net/revolunet/9e7Hy/

让我们组件更加友好

直接上代码:

<!-- lang: js -->
.directive(‘rnStepper‘, function() {
  return {
    // restrict and template attributes are the same as before.
    // we don‘t need anymore to bind the value to the external ngModel
    // as we require its controller and thus can access it directly
    scope: {},
    // the ‘require‘ property says we need a ngModel attribute in the declaration.
    // this require makes a 4th argument available in the link function below
    require: ‘ngModel‘,
    // the ngModelController attribute is an instance of an ngModelController
    // for our current ngModel.
    // if we had required multiple directives in the require attribute, this 4th
    // argument would give us an array of controllers.
    link: function(scope, iElement, iAttrs, ngModelController) {
      // we can now use our ngModelController builtin methods
      // that do the heavy-lifting for us

      // when model change, update our view (just update the div content)
      ngModelController.$render = function() {
        iElement.find(‘div‘).text(ngModelController.$viewValue);
      };

      // update the model then the view
      function updateModel(offset) {
        // call $parsers pipeline then update $modelValue
        ngModelController.$setViewValue(ngModelController.$viewValue + offset);
        // update the local view
        ngModelController.$render();
      }

      // update the value when user clicks the buttons
      scope.decrement = function() {
        updateModel(-1);
      };
      scope.increment = function() {
        updateModel(+1);
      };
    }
  };
});

这里,我不在需要内部变量value了。因为我们在link方法中已经拿到了ngModelController的引用,这里的ngModelController.$viewValue其实就是前面例子中的value。

但是我们又添加了另外一组键值对require: ‘ngModel‘。

我们使用了两个新的API:

ngModelController.$render: 在ngModel发生改变的时候框架自动调用,同步$modelValue和$viewValue, 即刷新页面。

ngModelController.$setViewValue: 当$viewValue发生改变时,通过此方法,同步更新$modelValue。
demo: http://jsfiddle.net/revolunet/s4gm6/

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

Javascript 相关文章推荐
jquery 学习之二 属性(html()与html(val))
Nov 25 Javascript
如何让div span等元素能响应键盘事件操作指南
Nov 13 Javascript
9行javascript代码获取QQ群成员具体实现
Oct 16 Javascript
JS小功能(onmouseover实现选择月份)实例代码
Nov 28 Javascript
Json实现异步请求提交评论无需跳转其他页面
Oct 11 Javascript
Js 正则表达式知识汇总
Dec 02 Javascript
jQuery性能优化技巧分析
Feb 20 Javascript
详解JavaScript中常用的函数类型
Nov 18 Javascript
AngularJS打开页面隐藏显示表达式用法示例
Dec 25 Javascript
如何给element添加一个抽屉组件的方法步骤
Jul 14 Javascript
layui 关闭open弹出框 刷新table表格页面的方法
Sep 16 Javascript
vue-router的钩子函数用法实例分析
Oct 26 Javascript
Boostrap实现的登录界面实例代码
Oct 09 #Javascript
深入理解bootstrap框架之第二章整体架构
Oct 09 #Javascript
javascript 判断是否是微信浏览器的方法
Oct 09 #Javascript
深入理解bootstrap框架之入门准备
Oct 09 #Javascript
微信小程序 http请求详细介绍
Oct 09 #Javascript
微信小程序 Flex布局详解
Oct 09 #Javascript
JavaScript实现Java中Map容器的方法
Oct 09 #Javascript
You might like
PHP连接MySQL查询结果中文显示乱码解决方法
2013/10/25 PHP
PHP如何实现Unicode和Utf-8编码相互转换
2015/07/29 PHP
前端必学之PHP语法基础
2016/01/01 PHP
php中加密解密DES类的简单使用方法示例
2020/03/26 PHP
写了10年的Javascript也未必全了解的连续赋值运算
2011/03/25 Javascript
将数字转换成大写的人民币表达式的js函数
2014/09/21 Javascript
jQuery内容过滤选择器用法分析
2015/02/10 Javascript
JavaScript 实现完美兼容多浏览器的复制功能代码
2015/04/28 Javascript
JavaScript实现带箭头标识的多级下拉菜单效果
2015/08/27 Javascript
Bootstrap基本样式学习笔记之表格(2)
2016/12/07 Javascript
使用AngularJS 跨站请求如何解决jsonp请求问题
2017/01/16 Javascript
JS回调函数简单用法示例
2017/02/09 Javascript
vue-cli 引入、配置axios的方法
2018/05/08 Javascript
jQuery移动端跑马灯抽奖特效升级版(抽奖概率固定)实现方法
2019/01/18 jQuery
JS回调函数深入理解
2019/10/16 Javascript
微信小程序网络请求实现过程解析
2019/11/06 Javascript
node.js使用mongoose操作数据库实现购物车的增、删、改、查功能示例
2019/12/23 Javascript
跟老齐学Python之集合的关系
2014/09/24 Python
查看Python安装路径以及安装包路径小技巧
2015/04/28 Python
Python装饰器使用实例:验证参数合法性
2015/06/24 Python
python按综合、销量排序抓取100页的淘宝商品列表信息
2018/02/24 Python
Python操作Oracle数据库的简单方法和封装类实例
2018/05/07 Python
详解Django-auth-ldap 配置方法
2018/12/10 Python
django项目中使用手机号登录的实例代码
2019/08/15 Python
pytorch numpy list类型之间的相互转换实例
2019/08/18 Python
通过实例解析python描述符原理作用
2020/01/22 Python
日本著名的平价时尚女性购物网站:Fifth
2016/08/24 全球购物
英国领先的电子、技术和办公用品购物网站:Ebuyer
2018/04/04 全球购物
美国唇部护理专家:Sara Happ
2019/06/19 全球购物
实习自荐信
2013/10/13 职场文书
计算机求职信
2013/12/01 职场文书
孕妇离婚协议书范本
2014/11/20 职场文书
工地材料员岗位职责
2015/04/11 职场文书
第一节英语课开场白
2015/06/01 职场文书
golang 实现Location跳转方式
2021/05/02 Golang
Win11 25163.1010更新补丁KB5016904推送,测试服务验证管道(附更新修复汇总)
2022/07/23 数码科技