使用Controller As方法访问继承的范围

New*_*Dev 44 angularjs angularjs-scope angularjs-controller

使用原始方式定义控制器,访问父级的范围相当简单,因为子范围原型继承自其父级.

app.controller("parentCtrl", function($scope){
   $scope.name = "Parent";
})
.controller("childCtrl", function($scope){
   $scope.childName = "child of " + $scope.name;
});

<div ng-controller="parentCtrl">
   {{name}}
   <div ng-controller="childCtrl">
      {{childName}}
   </div>
</div>
Run Code Online (Sandbox Code Playgroud)

Controller-As方法似乎是声明控制器的推荐方法.但是使用Controller-As,上述方法不再适用.

当然,我可以pc.name从View中访问父作用域:

<div ng-controller="parentCtrl as pc">
   {{pc.name}}
   <div ng-controller="childCtrl as cc">
      {{cc.childName}}
   </div>
</div>
Run Code Online (Sandbox Code Playgroud)

我确实遇到了一些问题(潜在的意大利面条代码),但这个问题是关于从子控制器访问父作用域.

我能看到这个工作的唯一方法是:

app.controller("parentCtrl", function(){
   this.name = "parent";
})
.controller("childCtrl", function($scope){
   $scope.pc.name = "child of " + $scope.name;
   // or
   $scope.$parent.pc.name = "child of " + $scope.name;

   // there's no $scope.name
   // and no $scope.$parent.name
});
Run Code Online (Sandbox Code Playgroud)

所以现在,子控制器需要知道" pc" - 除了,这应该(在我看来)被限制在视图中.我不认为子控制器应该知道视图决定声明一个ng-controller="parentCtrl as pc".

问:那么正确的方法是什么?

编辑:

澄清:我不打算继承父控制器.我希望继承/更改共享范围.所以,如果我要修改第一个例子,我应该能够做到以下几点:

app.controller("parentCtrl", function($scope){
   $scope.someObj = {prop: "not set"};
})
.controller("childCtrl", function($scope){
   $scope.someObj.prop = "changed";
});
Run Code Online (Sandbox Code Playgroud)

New*_*Dev 62

经过研究,我得出以下认识:

控制器 - 方法不能替代使用$scope.两者都有自己的位置,可以/应该明智地一起使用.

  1. $scope正如名称所暗示的那样:即它定义了ViewModel属性$scope.这最适合与嵌套控制器共享范围,嵌套控制器可以使用它$scope来驱动自己的逻辑或更改它.
  2. Controler-As将整个控制器对象定义为具有命名范围的ViewModel(通过控制器的别名).如果View决定是否要引用特定的控制器ViewModel,则这仅适用于View(但不适用于其他控制器).

这是一个例子:

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

// Then the controllers could choose whether they want to modify the inherited scope or not:
app.controller("ParentCtrl", function($scope) {
    this.prop1 = {
      v: "prop1 from ParentCtrl"
    };
    $scope.prop1 = {
      v: "defined on the scope by ParentCtrl"
    };
  })
  .controller("Child1Ctrl", function($scope) {})
  .controller("Child2Ctrl", function($scope) {
    // here, I don't know about the "pc" alias
    this.myProp = $scope.prop1.v + ", and changed by Child2Ctrl";
  });
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.8/angular.min.js"></script>

<body ng-app="myApp">
  <div ng-controller="ParentCtrl as pc">
     <div ng-controller="Child1Ctrl">
        <div>I know about the "pc" alias: {{pc.prop1.v}}</div>
     </div>
     <div ng-controller="Child2Ctrl as ch2">
       <div>I only care about my own ViewModel: {{ch2.myProp}}</div>
    </div>
  </div>
Run Code Online (Sandbox Code Playgroud)

  • 所以你基本上说在使用"控制器为"时访问子进程内的父进程是不可行的吗?我不认为OP($ scope.$ parent.pc.name)列出的方法是可行的. (2认同)

Whi*_*her 7

你应该这样做:

HTML

<div ng-controller="ChildController as child">
    <button type="button" ng-click="child.sayMe()">Say me!</button>
</div>
Run Code Online (Sandbox Code Playgroud)

JS

var app = angular.module('myApp', [])
app.controller('BaseController',function() {
    this.me = 'Base';
    this.sayMe= function() {
        alert(this.me);
    }
});
app.controller('ChildController', function($scope, $controller) {
    var controller = $controller('BaseController as base', {$scope: $scope});
    angular.extend(this, controller);
    this.me = 'Child';
});
Run Code Online (Sandbox Code Playgroud)

看看https://docs.angularjs.org/guide/controller