Passing variables by values without the dreaded if/switch/eval
Now The Angular Way™ to do this is to push off the data to a higher scope visible to both controllers and let two-way binding do its thing. This is typically done by using a parent controller. Scope operates similar to prototypal inheritance. If it's not in the child scope, it looks for it in the parent scope.



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

app.controller('ParentController', function($scope) {
  $scope.data = {
    data1: 'data1',
    data2: 'data2',
  }
});

app.controller('Ctrl1', function($scope) {
  // Stuff local to Ctrl 1
});


app.controller('Ctrl2', function($scope) {
  // Stuff local to Ctrl 2
});
&lt;script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"&gt;&lt;/script&gt;
&lt;div ng-app="plunker"&gt;
  &lt;div ng-controller="ParentController"&gt;
    &lt;div ng-controller='Ctrl1'&gt;
      Output 1: {{data.data1}}
      &lt;br&gt;Output 2: {{data.data2}}
    &lt;/div&gt;
    &lt;div ng-controller='Ctrl2'&gt;
      Input 1:
      &lt;input type='text' ng-model='data.data1'&gt;
      &lt;br&gt;Input 2:
      &lt;input type='text' ng-model='data.data2'&gt;
    &lt;/div&gt;
  &lt;/div&gt;
&lt;/div&gt;




This works for small apps. When your apps become large, it's better if you use a service/factory/provider. Use it to hold your data, expose an API to mutate the data and make it emit events when data changes. That way, controllers can pull them in as dependencies, call the API and listen to data changes.

As for other things, Angular allows you to define controllers with implicit dependency format. It uses the name of the variables introduced to the function as the names of the dependencies.