AngularJS中controller控制器继承的使用方法


Posted in Javascript onNovember 03, 2017

前沿

最近在angularjs项目当中,看到 controller 好多都是重复性的代码,在 controller 当中有好多代码很相似 function(比如 controller 下的 CRUD 方法),重复性工作太多。后来想,可不可以提出一个service ,但仔细想想,这些CRUD 本来就是从 Service 中调用的,如果在提出Service,会造成 Service 比较混乱,职责不清晰 。 因为自己做过一些后端,借助后端的思想,是不是可以 controller 继承。

 controllerservice实现继承经过一番查阅资料,发现AngularJS已经帮我们提供了controller继承。我们只需借助 controllerservice 。$controller service api

// 参数的解释
// constructor 可以是 function 也可以是 string 
//      如果传入一个 function, 就会当成 controller 的构造函数
//      如果传入一个 string,就会根据字符串去$controllerProvider 找 注册的 controller
//locals 是一个对象,注入来自局部的 controller ,在这里我们认为 child controller
$controller(constructor, locals, [bindings])

嵌套控制器中属性是如何被继承的?

==属性值是字符串

myApp.controller("ParentCtrl", function($scope){
  $scope.name = "darren";
})

myApp.controller("ChildCtrl", function($scope){

})

<div ng-controller="ParentCtrl">
  <label>父控制器中的name变量值</label> <input ng-model="name" />
  <div ng-controller="ChildCtrl">
     <label>子控制器中的name变量值</label> <input ng-model="name" />
     
     <ul>
      <li>child controller name: {{name}}</li>
      <li>parent controller name: {{$parent.name}}</li>
     </ul>
  </div>
</div>

以上,ParentCtrl中的name字段被ChildCtrl分享,但改变ChildCtrl中的name字段值却不会影响ParentCtrl中的name值,当改变ChildCtrl中的name值,ParentCtrl和ChildCtrl的嵌套关系被打破,再次改变ParentCtrl中的name字段值也不会影响ChildCtrl中的name值。

以上,给ParentCtrl中的变量赋值是字符串类型,如果给ParentCtrl中的字段赋值对象类型呢?

==属性值是对象

myApp.controller("ParentCtrl", function($scope){
  $scope.vm = {
    name: "John"
  };
})

myApp.controller("ChildCtrl", function($scope){

})

<div ng-controller="ParentCtrl">
  <label>父控制器中的vm.name变量值</label> <input ng-model="vm.name" />
  <div ng-controller="ChildCtrl">
     <label>子控制器中的vm.name变量值</label> <input ng-model="vm.name" />
     
     <ul>
      <li>child controller name: {{vm.name}}</li>
      <li>parent controller name: {{$parent.vm.name}}</li>
     </ul>
  </div>
</div>

以上,ParentCtrl中vm对象的被ChildCtrl分享,当然也分享了对象中的name字段,当改变ChildCtrl中的vm.name值会影响到ParentCtrl,也就是不会把ParentCtrl和ChildCtrl之间的嵌套关系打破。

嵌套控制器中方法是如何被继承的?

myApp.controller("ArrayCtrl", function($scope){
  $scope.myArray = ["John", "Andrew"];
  
  $scope.add = function(name){
    $scope.myArray.push(name);
  }
})

myApp.controller("CollectionCtrl", function($scope){

})

<div ng-controller="ArrayCtrl">
  <label>My Array:</label><span>{{myArray}}</span>
  
  <label>parent controller:</label>
  <input ng-model="parentName" />
  <button ng-click="add(parentName)">Add New Item</button>
  
  <div ng-controller="CollectionCtrl">
    <label>child controller:</label>
    <input ng-model="childName" />
    <input type="number" ng-model="index" />
    <button ng-click="add(childName)">Add New Item</button>
  </div>
</div>

使用ArrayCtrl中的add方法,添加没问题;而且ArrayCtrl中的add方法也可以被CollctionCtrl使用;

而且在子控制器中可以重写父控制器中的方法。

myApp.controller("CollectionCtrl", function($scope){
  //插入到某个位置
  $scope.add = function(name, index){
    $scope.myArray.splice(index,0, name);
  }
})

<div ng-controller="ArrayCtrl">
  <label>My Array:</label><span>{{myArray}}</span>
  
  <label>parent controller:</label>
  <input ng-model="parentName" />
  <button ng-click="add(parentName)">Add New Item</button>
  
  <div ng-controller="CollectionCtrl">
    <label>child controller:</label>
    <input ng-model="childName" />
    <input type="number" ng-model="index" />
    <button ng-click="add(childName, index)">Add New Item</button>
  </div>
</div>

代码案例

1.创建一个 base.controller.js 文件

(function() {
  'use strict';

  angular
    .module('DemoApp')
    .controller('BaseCtrl', BaseCtrl);

  //手动注入一些服务
  BaseCtrl.$inject = ['$scope','CRUDServices'];

  /* @ngInject */
  function BaseCtrl($scope,CRUDServices) {
    var _this = this;
    //当前 controller 提供一些方法
    _this.bFormValid = formValid;

    activate();

    ////////////////

    //初始化时候调用
    function activate() {

      getList();
    }

    // 获取数据列表
    function getList() {
      //把当前的结果赋值给 bList 属性上
      _this.bList = CRUDServices.getList();
    }

    // 表单验证
    function formValid(){

      //do some thing
      return false;
    }
  }
})();

代码很简单,我们在 BaseController中提供了一个简单的 formValid() 方法,还初始化调用了一个getList() 方法。

2.创建一个Service 。这个 service 来提供数据服务

(function() {
  'use strict';

  angular
    .module('DemoApp')
    .service('ExtendServices', ExtendServices);

  ExtendServices.$inject = [];

  /* @ngInject */
  function ExtendServices() {

    return {
      getList: getList  //获取 list 列表
    }

    ////////////////

    function getList() {
      return [{ id: 1, name: '张三' }, { id: 2, name: '李四' }]
    }
  }
})();

3.创建child.controller.js 文件 也就是我们最主要的一个文件

(function() {
  'use strict';

  angular
    .module('DemoApp')
    .controller('ChildCtrl', ChildCtrl);

  //手动注入一些服务
  //ExtendServices 用来提供数据的 Servie
  ChildCtrl.$inject = ['$scope', '$controller','ExtendServices'];

  /* @ngInject */
  function ChildCtrl($scope, $controller,ExtendServices) {

    var vm = this;

    //调用我们父 controller 
    var parentCtrl = $controller('BaseCtrl', { $scope, $scope,CRUDServices:ExtendServices })

    //通过 angular.extend 把父控制器上的 方法和属性 绑定到 子的对象上
    angular.extend(vm, parentCtrl);


    activate();

    ////////////////

    function activate() {
      
      //调用表单验证方法
      vm.bFormValid();      
      
    }
  }
})();

这样,我们通过 $controller service 实现了 controller 的继承 ,也可以把 child controller 需要的注入的服务 传入到 base controller 当中 。({ $scope, $scope,CRUDServices:ExtendServices }),我们child controlller 一行代码都没有写,就已经用了 获取 列表的 magic power 。如果我们需要调用表单验证,直接调用 vm.bFormValid() 就可以。

4.创建child.html 文件 ,我们直接 绑定就ok

<div>
  <!-- 直接绑定 vm.bList 就会看到输出结果-->
  <div ng-repeat="item in vm.bList">{{item}}</div>
</div>

结束语

这样下来以后我们可以提出一个 公共的 controller ,封装一些常用的方法,在 controller当中,只需要去写关于业务不同的 方法。 代码可维护性大大提高,代码量也会减下来。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
javascript 日期时间函数(经典+完善+实用)
May 27 Javascript
js 有框架页面跳转(target)三种情况下的应用
Apr 09 Javascript
JavaScript实现为指定对象添加多个事件处理程序的方法
Apr 17 Javascript
javascript通过获取html标签属性class实现多选项卡的方法
Jul 27 Javascript
纯JS实现可拖拽表单的简单实例
Sep 02 Javascript
js实现右键自定义菜单
Dec 03 Javascript
vue 注册组件的使用详解
May 05 Javascript
JavaScript引用类型Array实例分析
Jul 24 Javascript
小程序获取周围IBeacon设备的方法
Oct 31 Javascript
详解Vue-axios 设置请求头问题
Dec 06 Javascript
使vue实现jQuery调用的两种方法
May 12 jQuery
vue使用websocket的方法实例分析
Jun 22 Javascript
vue解决跨域路由冲突问题思路解析
Nov 03 #Javascript
React-intl 实现多语言的示例代码
Nov 03 #Javascript
ztree实现左边动态生成树右边为内容详情功能
Nov 03 #Javascript
基于angular-utils-ui-breadcrumbs使用心得(分享)
Nov 03 #Javascript
详解React-Native全球化多语言切换工具库react-native-i18n
Nov 03 #Javascript
js 客户端打印html 并且去掉页眉、页脚的实例
Nov 03 #Javascript
微信小程序自动客服功能
Nov 02 #Javascript
You might like
php 友好URL的实现(吐血推荐)
2008/10/04 PHP
解析PHP SPL标准库的用法(遍历目录,查找固定条件的文件)
2013/06/18 PHP
php多文件上传下载示例分享
2014/02/20 PHP
[原创]PHP正则匹配中英文、数字及下划线的方法【用户名验证】
2017/08/01 PHP
PHP面向对象程序设计重载(overloading)操作详解
2019/06/13 PHP
jquery移动节点实例
2015/01/14 Javascript
javascript拖拽应用实例
2016/03/25 Javascript
JS实现简易的图片拖拽排序实例代码
2017/06/09 Javascript
JavaScript正则表达式和级联效果
2017/09/14 Javascript
vue 中directive功能的简单实现
2018/01/05 Javascript
快速解决Vue项目在IE浏览器中显示空白的问题
2018/09/04 Javascript
js+html实现周岁年龄计算器
2019/06/25 Javascript
对TypeScript库进行单元测试的方法
2019/07/18 Javascript
js get和post请求实现代码解析
2020/02/06 Javascript
解决vue动态路由异步加载import组件,加载不到module的问题
2020/07/26 Javascript
[36:05]完美世界DOTA2联赛循环赛 Forest vs DM 第一场 11.06
2020/11/06 DOTA
python判断字符串编码的简单实现方法(使用chardet)
2016/07/01 Python
python 列表删除所有指定元素的方法
2018/04/19 Python
如何利用Anaconda配置简单的Python环境
2019/06/24 Python
在Python中实现函数重载的示例代码
2019/12/12 Python
浅谈Python 命令行参数argparse写入图片路径操作
2020/07/12 Python
python实现发送QQ邮件(可加附件)
2020/12/23 Python
Html5自定义字体解决方法
2019/10/09 HTML / CSS
英国时尚女装购物网站:Missguided
2018/08/23 全球购物
Probikekit欧盟:在线公路自行车专家
2019/07/12 全球购物
PyQt QMainWindow的使用示例
2021/03/24 Python
怎样写好自我鉴定
2013/12/04 职场文书
初中同学会活动方案
2014/08/22 职场文书
爱心捐款活动总结
2015/05/09 职场文书
预备党员转正意见
2015/06/01 职场文书
《黄道婆》教学反思
2016/02/22 职场文书
2019年教师入党申请书
2019/06/27 职场文书
Python机器学习之决策树和随机森林
2021/07/15 Javascript
nginx从安装到配置详细说明(安装,安全配置,防盗链,动静分离,配置 HTTPS,性能优化)
2022/02/12 Servers
中国十大神话动漫电影排行榜 哪吒登顶 白蛇缘起排第七
2022/03/21 国漫
Spring 使用注解开发
2022/05/20 Java/Android