How to inherit from base controller using “control

2019-07-21 10:45发布

问题:

Here is a snippet demonstrating how to inherit from a base controller using $controller and $scope:

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

app.controller('MainCtrl', function($scope, $controller) {
  $controller('BaseCtrl', {
    $scope: $scope
  })
});

app.controller('BaseCtrl', function($scope) {
  $scope.name = 'World';
});
<!DOCTYPE html>
<html ng-app="app">

<head>
  <meta charset="utf-8" />
  <title>AngularJS</title>
  <script>
    document.write('<base href="' + document.location + '" />');
  </script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
  <script src="app.js"></script>
</head>

<body ng-controller="MainCtrl">
  <p>Hello {{name}}!</p>
</body>

</html>

How can I do the same using "controller as" syntax? This snippet demonstrates what I am after, but it doesn't work:

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

app.controller('MainCtrl', function($scope, $controller) {
  $controller('BaseCtrl', {
    $scope: $scope
  })
});

app.controller('BaseCtrl', function() {
  this.name = 'World';
});
<!DOCTYPE html>
<html ng-app="app">

<head>
  <meta charset="utf-8" />
  <title>AngularJS</title>
  <script>
    document.write('<base href="' + document.location + '" />');
  </script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
  <script src="app.js"></script>
</head>

<body ng-controller="MainCtrl as main">
  <p>Hello {{main.name}}!</p>
</body>

</html>

回答1:

You could use controller as syntax (or just use the ctrl instance returned by $controller provider) and use angular.extend. But i don't think there is another way implicitly angular would do this, since "controller as" syntax ultimately places the controller instance on the respective scope as a property name specified as alias. But this really isn't inheritance, but utilizing object extension.

var ctrl = $controller('BaseCtrl as base', { //You don't really need to use as syntax here though
   $scope: $scope
});

angular.extend(this, ctrl);

//or

$controller('BaseCtrl as base', { //You don't really need to use as syntax here though
   $scope: $scope
});
angular.extend(this, $scope.base); //With as syntax 

Or you could use prototypical inheritance at the implementation level of the controller constructors itself. There are lots of syntactic sugars available, typescript's extends there is another nice and simple example here as well.

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

app.controller('MainCtrl', function($scope, $controller) {
 var ctrl = $controller('BaseCtrl as base', {
    $scope: $scope
  });
 
  angular.extend(this, ctrl);
});

app.controller('BaseCtrl', function() {
  this.name = 'World';
});
<!DOCTYPE html>
<html ng-app="app">

<head>
  <meta charset="utf-8" />
  <title>AngularJS</title>
  <script>
    document.write('<base href="' + document.location + '" />');
  </script>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
  <script src="app.js"></script>
</head>

<body ng-controller="MainCtrl as main">
  <p>Hello {{main.name}}!</p>
</body>

</html>