2015-03-09 2 views

ответ

3

Вам необходимо ввести службу явно. Контроллер ребенок наследует сферу, но, конечно, сервис не на объект области видимости (если не поставить его там)

увидеть эту jsfiddle, чтобы доказать это: http://jsfiddle.net/HB7LU/11596/

var myApp = angular.module('myApp',[]); 

myApp.factory('serviceId', function() { 
    var a = 1; 
    return { 
     a: a 
    }; 
}); 

myApp.controller('Ctrl',['$scope', 'serviceId' ,function($scope, serviceId) { 
    $scope.name = 'Superhero' + serviceId.a; 
}]) 

myApp.controller('ChildCtrl',['$scope',function($scope) { 

    // the next line throws an undefined error because of serviceId 
    $scope.name = 'Superhero' + serviceId.a; 
}]) 
1

Если вы прототипичный наследство, то вы можете иметь поле из родительского контроллера как нечто, что можно использовать в производном контроллере. Чтобы наследовать угловые контроллеры js, вам нужно сделать несколько вещей. Надеюсь, следующее объяснение будет более ясным.

Прототипическое наследование в JavaScript

Так, чтобы начать с возможностью определить, каким образом мы будем прототипический наследовать от объекта. В JavaScript Прототипом наследование может быть сделано следующим образом:

function Foo(some_param) 
{ 
    this.some_param = some_param 
} 

function Bar(some_param, some_specialized_param) 
{ 
    /** 
    * Call the super class constructor 
    */ 
    Foo.call(this, some_param); 
    this.some_specialized_param = some_specialized_param; 
} 

/** 
* Now that you have defined the constructor, you need to 
* define the prototypical inheritance 
*/ 
Bar.prototype = Object.create(Foo.prototype); 

/** 
* Now you have to set the constructor 
*/ 
Bar.prototype.constructor = Bar; 

Таким образом, используя этот пример, вы можете создать angularjs контроллеры. Однако есть одна проблема. Если, например, класс Bar находится в другом модуле или каталоге, вам нужно импортировать определение. Вы можете использовать какой-либо другой инструмент, например RequireJS, для загрузки определения модуля/контроллера/класса в файле, где Bar определен, а затем наследовать следующим образом. Вы, однако, можете также использовать angularjs конструкцию следующим образом:

Контроллер наследования в AngularJS

Таким образом, вы можете использовать два angularjs конструкции, чтобы определить точку создания экземпляра в контроллере (angular.module (..) конструктор.) И определение контроллера (угловой.модуль (..). завод). Установки AngularJS могут использоваться для определения класса контроллера.

angular.module('some_module') 
.factory('BaseCtrlClass', ['aService', function(aService) 
{ 
    function BaseCtrl($scope) 
    { 
     /** 
     * Assign a reference to "aService" 
     * which is injected whithin this factory 
     */ 
     this.aService = aService; 
     this.$scope = $scope; 
    } 

    return BaseCtrl; 
}]); 

Теперь вы можете определить определение контроллера, так что вы можете создать его экземпляр с помощью ngController как:

angular.module('some_module') 
.controller('BaseCtrl', [$scope, 'BaseCtrlClass', function($scope, BaseCtrlClass) 
{ 
    return new BaseCtrlClass($scope); 
}]); 

Обратите внимание, что на заводе я определил его как BaseCtrlClass, потому что это определение класса. В конструкции контроллера я определил BaseCtrl, что вы можете использовать извне, как упоминалось, используя ngController. Имя BaseCtrlClass должно использоваться внутри производных контроллеров, как мы увидим ниже. Как я уже упоминал, проблема возникает, когда вы пытаетесь импортировать определение BaseCtrlClass в другой файл/модуль в идеале - файл, определяющий класс DerivedCtrl. Позволяет определить DerivedCtrl класс следующим образом:

angular.module('a_different_module') 
.factory('DerivedCtrlClass', ['BaseCtrlClass', function(BaseCtrlClass) 
{ 
    function DerivedCtrl($scope, aDifferentService) 
    { 
     BaseCtrlClass.call(this, $scope); 
     this.aDifferentService = aDifferentService //Specialized resource 
    } 

    DerivedCtrl.prototype = Object.create(BaseCtrlClass.prototype); 
    DerivedCtrl.prototype.constructor = DerivedCtrl;   

    return DerivedCtrl; 
}]) 
.controller('DerivedCtrl', ['$scope', 'aDiferentService', 'DerivedCtrlClass', function($scope, aDifferentService, DerivedCtrlClass) 
{ 
    return new DerivedCtrlClass($scope, aDifferentService); 
}]); 

Так здесь вы можете увидеть, что я определил DerivedCtrl на заводе под названием DerivedCtrlClass. Это существенно определяет определение класса контроллера. Таким образом, любой другой модуль или класс, пытающийся наследовать от этого, может использовать эту фабрику. В конструкторе я вызвал конструктор BaseCtrlClass, передающий «this» и «$ scope» в качестве аргументов, которые требуются. Позже я определил конструкции прототипов и конструктор по умолчанию, аналогичный примеру javascript, о котором я упоминал ранее. Для удобства я также определил конструкцию контроллера, которая также может использоваться с ngController.

Главное, что я хочу подчеркнуть, что экземпляр DerivedCtrl теперь можно использовать

this.aService 

, которая является то, что определено в BaseCtrl. В принципе все, что определено в рамках BaseCtrl и DerivedCtrl, теперь можно использовать в экземпляре DerivedCtrl. Это работает достаточно хорошо в HTML, когда вы пытаетесь определить DerivedCtrl вы можете просто сделать

<div ng-controller="DerivedCtrl"> 
    ...... 
</div> 

наследование Scoped

Если вы хотите, однако, имеют контекстное наследство вы можете использовать что-то вроде этого:

<div ng-controller="BaseCtrl"> 
    <div ng-controller="DerivedCtrl"> 
     ... 
    </div> 
</div> 

Проблема в том, что вам нужно связывать поля с помощью $ scope. В конструкторе BaseCtrl вам нужно сделать следующее:

$scope.aService = aService 

А потом из DerivedCtrl вы можете использовать $ scope.aService. Это не так хорошо работает, потому что оно прерывает инкапсуляцию. Для удобства обслуживания вы можете не экспортировать эту услугу и сделать ее псевдозащитой только для доступа к классам, которые наследуются от BaseCtrl. В этом случае решение, которое я предоставил, отлично работает, по крайней мере, я использовал этот способ.

Надеюсь, это поможет.

Смежные вопросы