2016-04-05 102 views
1

我只是碰到一个示例代码对角JS控制器继承从这个网址http://viralpatel.net/blogs/angularjs-controller-tutorial/角JS控制器继承问题

这里是代码,我只是不明白一个组成部分。

<div ng-controller="BMWController"> 

    My name is {{ name }} and I am a {{ type }} 

    <button ng-click="clickme()">Click Me</button> 

</div> 


<script> 
function CarController($scope) { 

    $scope.name = 'Car'; 
    $scope.type = 'Car'; 

    $scope.clickme = function() { 
     alert('This is parent controller "CarController" calling'); 
    } 

} 

function BMWController($scope, $injector) { 

    $injector.invoke(CarController, this, {$scope: $scope}); 

    $scope.name = 'BMW'; 

} 
</script> 

1)我只是不明白这行代码$injector.invoke(CarController, this, {$scope: $scope});

2),其中价值范围BMWController范围和$范围CarController范围是什么?

3)有两个范围{$ scope:$ scope}一个在左边和一个在右边哪一个与有关BMWController & CarController scope?

4)为什么在调用函数中使用此关键字? 5)请帮我理解这一行$ injector.invoke(CarController,this,{$ scope:$ scope});

感谢

回答

1

内读取Doc后,我认为这些线意味着你:

  1. $injector.invoke(CarController...:调用CarController功能;
  2. ... , this ...:对调用者的引用;
  3. ...{$scope: $scope}):CarController具有$ scope的依赖关系,所以这一行意味着您将第BmwController $ scope注入到CarController中。

除此之外,我真的认为控制器继承是一个非常糟糕的做法。如果你需要在两个控制器之间共享一些逻辑,你应该使用Angular Services。它们是单应用程序,在应用程序的所有生命周期中都存在,旨在存储逻辑或数据,更重要的是,使您的控制器保持外观和优雅。

看看这个例子:

https://jsfiddle.net/relferreira/2b5amcya/

HTML:

<div data-ng-app="app"> 

    <div data-ng-controller="MainController as mainVm"> 
    {{mainVm.name}} 
    </div> 

    <div data-ng-controller="DetailController as detailVm"> 
    {{detailVm.name}} 
    {{detailVm.other}} 
    </div> 

</div> 

JS:

angular.module('app', []); 

angular.module('app') 
    .controller('MainController', mainController); 

mainController.$inject = ['UserService']; 

function mainController(UserService){ 

    var vm = this; 
    vm.name = UserService.getName(); 

} 

angular.module('app') 
    .controller('DetailController', detailController); 

detailController.$inject = ['UserService']; 

function detailController(UserService){ 

    var vm = this; 
    vm.name = UserService.getName(); 
    vm.other = 'test'; 

} 

angular.module('app') 
    .factory('UserService', userService); 

function userService(){ 
    var name = 'Renan'; 
    return{ 
    getName: getName 
    } 

    function getName(){ 
    return name; 
    } 
} 

编辑

望着AngularJs源代码,我们可以发现invoke方法:

function invoke(fn, self, locals, serviceName) { 
     if (typeof locals === 'string') { 
     serviceName = locals; 
     locals = null; 
     } 

     var args = injectionArgs(fn, locals, serviceName); 
     if (isArray(fn)) { 
     fn = fn[fn.length - 1]; 
     } 

     if (!isClass(fn)) { 
     // http://jsperf.com/angularjs-invoke-apply-vs-switch 
     // #5388 
     return fn.apply(self, args); 
     } else { 
     args.unshift(null); 
     return new (Function.prototype.bind.apply(fn, args))(); 
     } 
    } 

正如你所看到的,它使用的是Function.prototype.apply()方法。如Alex所述,这种方法需要一个上下文,并且它最常用于继承和/或覆盖方法。看看这个答案:

https://stackoverflow.com/a/560952/1108979

它使用call方法,即类似于apply

+0

我如何知道服务是单身人士?我们可以写任何代码证明服务是单身...寻找指导。谢谢 – Mou

+0

当我们调用'$ injector.invoke()'给我想法时,为什么我们需要传递'this关键字' – Mou

+0

他们是按定义单身。看看文档(https://docs.angularjs.org/guide/services)。 –

2

1)你运行一个函数(CarController),并提供其参数($scope

2)你通过电流(的BMWController)范围的CarController尽可能多的方便解释,所以他们共享范围。

3)行{$scope: $scope}用密钥$scope创建一个对象,并用对象$scope初始化它。尝试看看第一$scope就像任何其他对象键,像name将是{name: 'Mou'}

4)调用只是运行具有给定参数的函数:$injector documentation

你传递一个函数的调用函数,但该功能没有上下文。你需要告诉它你想在哪里运行它。因此,通过将本该是BMWController它运行它种的BMWController

+0

为什么我们需要传递'这个keyword'当我们调用'$ injector.invoke()'给我的想法 – Mou

+0

既然你需要调用 – AlexD

+0

的背景不清楚ü解释的方式。 – Mou

2

$injector.invoke(CarController, this, {$scope: $scope});调用函数CarController并传递BMWController$scope作为参数。

你可以看到它像:

function CarController($scope) { 
    // ...  
} 
function BMWController($scope, $injector) { 
    CarController($scope); 
    $scope.name = 'BMW'; 
} 

,您还可以通过其他的参数,如:

function CarController($scope, foo) { 
    // ... 

} 

function BMWController($scope, $injector) { 
    // ... 
    $injector.invoke(CarController, this, {$scope: $scope, foo: bar}); 
} 

因此,而不是直接调用控制器功能,您使用依赖注入调用它。依赖注入是具有多个优点的设计模式,如解释here

编辑

this的可选参数的invoke功能$injector.invoke(fn, [self], [locals]);和用于传递当前上下文:BMWController到被调用的控制器功能CarController

在此示例中,我们在BMWController上下文中定义this.foo,然后我们可以在CarController上下文中访问foo

function CarController($http, $scope) { 
    console.log(this.foo) // prints: bar 
    // .... 
} 
function BMWController($scope, $injector) { 
    this.foo = "bar"; 

    $injector.invoke(CarController, this, { $scope: $scope }); 
    // .... 
} 
+0

当我们调用'$ injector.invoke()'给我想法 – Mou

+0

我为什么需要传递'this关键字'我更新了答案,并在我们传递时通过'this'' – Lulylulu

+0

的解释这个关键字CarController函数然后这个参考将被存储的地方,因为CarController函数没有这个keywor的参数? – Mou