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 相关文章推荐
两个多选select(multiple左右)添加、删除选项和取值实例
May 12 Javascript
ajax读取数据后使用jqchart显示图表的方法
Jun 10 Javascript
js实现Select列表内容自动滚动效果代码
Aug 20 Javascript
jQuery实现图片预加载效果
Nov 27 Javascript
纯js代码实现简单计算器
Dec 02 Javascript
使用Curl命令查看请求响应时间方法
Nov 04 Javascript
值得分享的Bootstrap Table使用教程
Nov 23 Javascript
js仿微信公众平台打标签功能
Apr 08 Javascript
Node.js中环境变量process.env的一些事详解
Oct 26 Javascript
基于vue cli重构多页面脚手架过程详解
Jan 23 Javascript
Angular浏览器插件Batarang介绍及使用
Feb 07 Javascript
video.js添加自定义组件的方法
Dec 09 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之CodeIgniter学习笔记
2013/06/17 PHP
PHP实现二叉树的深度优先与广度优先遍历方法
2015/09/28 PHP
Laravel框架之解决前端显示图片问题
2019/10/24 PHP
利用XMLHTTP传递参数在另一页面执行并刷新本页
2006/10/26 Javascript
js利用div背景,做一个竖线的效果。
2008/11/22 Javascript
用JavaScript对JSON进行模式匹配(Part 1-设计)
2010/07/17 Javascript
jquery中:input和input的区别分析
2011/07/13 Javascript
javascript-表格排序(降序/反序)实现介绍(附图)
2013/05/30 Javascript
用js来获取上传的文件名纯粹是为了美化而用
2013/10/23 Javascript
jquery trigger伪造a标签的click事件取代window.open方法
2014/06/23 Javascript
JavaScript制作简单分页插件
2016/09/11 Javascript
利用JS判断客户端类型你应该知道的四种方法
2017/12/22 Javascript
Angular中使用better-scroll插件的方法
2018/03/27 Javascript
解决Vue中mounted钩子函数获取节点高度出错问题
2018/05/18 Javascript
node.js 模块和其下载资源的镜像设置的方法
2018/09/06 Javascript
微信小程序 函数防抖 解决重复点击消耗性能问题实现代码
2019/09/12 Javascript
JS如何生成随机验证码
2020/03/02 Javascript
react 不用插件实现数字滚动的效果示例
2020/04/14 Javascript
webpack+vue.js构建前端工程化的详细教程
2020/05/10 Javascript
快速解决vue2+vue-cli3项目ie兼容的问题
2020/11/17 Vue.js
[01:01:52]DOTA2-DPC中国联赛定级赛 SAG vs iG BO3第二场 1月9日
2021/03/11 DOTA
详解在Python的Django框架中创建模板库的方法
2015/07/20 Python
python画一个玫瑰和一个爱心
2020/08/18 Python
Python进程间通信 multiProcessing Queue队列实现详解
2019/09/23 Python
python绘制随机网络图形示例
2019/11/21 Python
Python time库基本使用方法分析
2019/12/13 Python
python GUI库图形界面开发之PyQt5信号与槽的高级使用技巧(自定义信号与槽)详解与实例
2020/03/06 Python
Tom Dixon官网:英国照明及家具设计和制造公司
2019/03/01 全球购物
大学生自我鉴定
2013/12/16 职场文书
财务主管的岗位职责
2013/12/30 职场文书
医德医风自我评价
2014/09/19 职场文书
意外死亡赔偿协议书
2014/10/14 职场文书
2014年妇产科工作总结
2014/12/08 职场文书
大学生党性分析材料
2014/12/19 职场文书
婚礼答谢词
2015/01/04 职场文书
pandas中DataFrame数据合并连接(merge、join、concat)
2021/05/30 Python