视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
AngularJS中controller控制器继承的使用方法
2020-11-27 22:26:26 责编:小采
文档

前沿

最近在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当中,只需要去写关于业务不同的 方法。 代码可维护性大大提高,代码量也会减下来。

下载本文
显示全文
专题