使用/ Angular'控制器继承N#39;与$范围

时间:2015-02-05 19:11:24

标签: angularjs inheritance angularjs-scope angularjs-controller

TL:博士;

我想将'控制器视为'简化我的继承过程的方法然而,我看到了依赖注入和指令中使用的一些陷阱。


前言

在过去的6个月里,我一直在研究一个非常大的Angular应用程序。我来自更多的OOP语言背景,但我觉得我已经很好地适应了javaScript和Angular的一些怪癖。

随着这种复杂性的应用,我认为它需要伟大的架构解决方案。我已经选择使用baseController类,UI控制器可以使用下面的当前方法继承这些类。

目前的做法

所有当前的UI视图/组件/等。正在使用 $ scope 作为视图模型方法,又名。 经典方法。我实现了控制器继承:

NxBaseUiController
var NxBaseUiController = function($scope)
{
    $scope.isLoggedIn = function(){}
    $scope.doSomethingElse = function(){}
}

这是一个子类基本控制器及其继承

NxBaseListUiController
var NxBaseListUiController = function($scope)
{
    var NxBaseUiController = require( './NxBaseUiController' )
    NxBaseUiController.apply( this, arguments )
    NxBaseListUiController .prototype = Object.create( NxBaseUiController.prototype );

    $scope.query = require( './QueryModel' ).new()
}

这种方法的疯狂之处在于,我必须保持2系列继承,同时牢记在视图层次结构中发生的现有NG范围继承。您可以在以下UML图中看到这一点:

Crnt inheritance UML diagram src - http://i.imgur.com/LNBhiVA.png

到目前为止这一切都有效,但是转到应用程序的新部分,我想开始查看“控制器”作为'语法,看看是否可以对上述方法进行任何简化。

的问题

在我所见过的所有“控制器”的例子中,'方法,附加的任何方法都是 not 在原型上定义,而是实际的构造函数,如下所示:

function SomeController($scope)
{
   this.foo = function(){}; 
}

您是否有理由不想在原型上定义控制器方法?

我认为附加到原型有问题的唯一原因是你失去了对注入的依赖项的引用。


我意识到我是从一个非常OO的方法来实现这个目标,但是这个大小的应用,能够利用继承等开发模式似乎是解决代码重复的必要条件。

我完全倒退了吗?是否有任何经过验证的方法可以在控制器中实现某些类似的继承,而这些方法并不需要一些难以理解的黑客工作?

1 个答案:

答案 0 :(得分:2)

没有理由你不能使用原型,只要你没有能力拥有实际的私人数据而不是传统的私人数据。

让我用代码解释一下:

function MyClass($http){
  var privateData = 123,
      $this = this;

  $this.getAnswer = function(){
     return privateData;
  };
}

MyClass.$inject = ['$http'];

在该示例中,一旦实例化了类,就无法实际更改privateData

function MyClass($http){
  this._privateData = 123;
  this.$http = $http;
}

MyClass.$inject = ['$http']; 

MyClass.prototype = {
   getAnswer: function(){
      return this._privateData;
   },
   callHome: function(){
      var _this = this;

      _this.$http.get('/api/stuff')
         .success(function(data){
            _this.stuff = data;
         });
   }
};

在这个例子中,我只是使用一个约定,即使用下划线(_)为我的属性添加前缀,以表示它们应被视为私有。

除非您正在构建可重用的库,否则这可能不是什么大问题。

请注意,使用ES6可以简化一些,如果我是你,我会调查6to5TypeScript之类的内容。你的OO背景可能会更好地凝胶化以编写如下代码:

//100% valid ES6
class MyClass extends BaseClass {
   constructor(something){
      super(something, 'foo');
   }

   someMethod(){
      return this.foo;
   }
}
相关问题