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 相关文章推荐
Javascript new关键字的玄机 以及其它
Aug 25 Javascript
jquery.simple.tree插件 更简单,兼容性更好的无限树插件
Sep 03 Javascript
实现51Map地图接口(示例代码)
Nov 22 Javascript
JS过滤url参数特殊字符的实现方法
Dec 24 Javascript
JavaScript实现同一页面内两个表单互相传值的方法
Aug 12 Javascript
JS中取二维数组中最大值的方法汇总
Apr 17 Javascript
Javascript oop设计模式 面向对象编程简单实例介绍
Dec 13 Javascript
基于js 本地存储(详解)
Aug 16 Javascript
jQuery图片缩放插件smartZoom使用实例详解
Aug 25 jQuery
webuploader实现上传图片到服务器功能
Aug 16 Javascript
vue fetch中的.then()的正确使用方法
Apr 17 Javascript
el-table表头根据内容自适应完美解决表头错位和固定列错位
Jan 07 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 压缩文件夹的类代码
2009/11/05 PHP
解析php开发中的中文编码问题
2013/08/08 PHP
PHP使用Pear发送邮件(Windows环境)
2016/01/05 PHP
JsEasy简介 JsEasy是什么?与下载
2007/03/07 Javascript
简单的js分页脚本
2009/05/21 Javascript
利用WebBrowser彻底解决Web打印问题(包括后台打印)
2009/06/22 Javascript
JS 获取span标签中的值的代码 支持ie与firefox
2009/08/24 Javascript
Mootools 1.2教程 滑动效果(Slide)
2009/09/15 Javascript
js 一个关于图片onload加载的事
2013/11/10 Javascript
jquery实现鼠标经过显示下划线的渐变下拉菜单效果代码
2015/08/24 Javascript
拖动时防止选中
2017/02/03 Javascript
jQuery Validate 相关参数及常用的自定义验证规则
2017/03/06 Javascript
angularJS模态框$modal实例代码
2017/05/27 Javascript
Angular+Bootstrap+Spring Boot实现分页功能实例代码
2017/07/21 Javascript
vue2.0 computed 计算list循环后累加值的实例
2018/03/07 Javascript
vue自定义指令之面板拖拽的实现
2019/04/14 Javascript
深入理解vue中的slot与slot-scope
2019/04/22 Javascript
[05:02][DOTA2]DOTA进化论 第一期
2013/09/27 DOTA
举例讲解Python设计模式编程中的访问者与观察者模式
2016/01/26 Python
python 全文检索引擎详解
2017/04/25 Python
Python3简单实例计算同花的概率代码
2017/12/06 Python
Python函数中不定长参数的写法
2019/02/13 Python
Django如何使用redis作为缓存
2020/05/21 Python
伦敦剧院门票:London Theatre Direct
2018/11/21 全球购物
中专自我鉴定
2014/02/05 职场文书
运动会入场词100字
2014/02/06 职场文书
预防艾滋病宣传标语
2014/06/25 职场文书
土地转让协议书
2014/09/27 职场文书
2014年科研工作总结
2014/12/03 职场文书
2015年端午节活动总结
2015/02/11 职场文书
爱心捐助活动总结
2015/05/09 职场文书
学生会部长竞选稿
2015/11/19 职场文书
会计工作自我鉴定范文
2019/06/21 职场文书
浅谈Redis位图(Bitmap)及Redis二进制中的问题
2021/07/15 Redis
浅谈Java父子类加载顺序
2021/08/04 Java/Android
CentOS 7安装mysql5.7使用XtraBackUp备份工具命令详解
2022/04/12 MySQL