我有两个Angular控制器:

function Ctrl1($scope) {
    $scope.prop1 = "First";
}

function Ctrl2($scope) {
    $scope.prop2 = "Second";
    $scope.both = Ctrl1.prop1 + $scope.prop2; //This is what I would like to do ideally
}

我不能在Ctrl2中使用Ctrl1,因为它是未定义的。然而,如果我试图像这样传递它。

function Ctrl2($scope, Ctrl1) {
    $scope.prop2 = "Second";
    $scope.both = Ctrl1.prop1 + $scope.prop2; //This is what I would like to do ideally
}

我得到一个错误。有人知道怎么做吗?

Ctrl2.prototype = new Ctrl1();

也失败了。

注意:这些控制器彼此之间不是嵌套的。


当前回答

——我知道这个答案不适合这个问题,但我希望阅读这个问题并希望处理工厂等服务的人避免这样做的麻烦----

为此,您将需要使用服务或工厂。

服务是在非嵌套控制器之间共享数据的最佳实践。

关于数据共享这个主题的一个非常非常好的注释是如何声明对象。我很不幸,因为我在阅读AngularJS之前就掉进了一个陷阱,我非常沮丧。所以让我帮你避免这个麻烦。

我从“ng-book: the complete book on AngularJS”中读到,AngularJS的ng-models在控制器中创建为裸数据是错误的!

$scope元素应该像这样创建:

angular.module('myApp', [])
.controller('SomeCtrl', function($scope) {
  // best practice, always use a model
  $scope.someModel = {
    someValue: 'hello computer'
  });

而不是像这样:

angular.module('myApp', [])
.controller('SomeCtrl', function($scope) {
  // anti-pattern, bare value
  $scope.someBareValue = 'hello computer';
  };
});

这是因为DOM(html文档)建议(最佳实践)将调用包含为

<div ng-model="someModel.someValue"></div>  //NOTICE THE DOT.

这对于嵌套控制器非常有用,如果你想让你的子控制器能够从父控制器....改变一个对象

但在您的情况下,您不需要嵌套作用域,但是有一个类似的方面可以从服务获取对象到控制器。

假设你有一个服务“Factory”,在返回空间中有一个objectA,它包含objectB, objectB又包含objectC。

如果你想从你的控制器GET对象tc到你的作用域,这样说是错误的:

$scope.neededObjectInController = Factory.objectA.objectB.objectC;

那没用的… 相反,只用一个点。

$scope.neededObjectInController = Factory.ObjectA;

然后,在DOM中,您可以从objectA调用objectC。这是与工厂相关的最佳实践,最重要的是,它将有助于避免意外和不可捕捉的错误。

其他回答

我喜欢用简单的例子来说明简单的事情:)

下面是一个非常简单的服务示例:


angular.module('toDo',[])

.service('dataService', function() {

  // private variable
  var _dataObj = {};

  // public API
  this.dataObj = _dataObj;
})

.controller('One', function($scope, dataService) {
  $scope.data = dataService.dataObj;
})

.controller('Two', function($scope, dataService) {
  $scope.data = dataService.dataObj;
});

这里是jsbin

这里有一个非常简单的Factory示例:


angular.module('toDo',[])

.factory('dataService', function() {

  // private variable
  var _dataObj = {};

  // public API
  return {
    dataObj: _dataObj
  };
})

.controller('One', function($scope, dataService) {
  $scope.data = dataService.dataObj;
})

.controller('Two', function($scope, dataService) {
  $scope.data = dataService.dataObj;
});

这里是jsbin


如果这太简单了,这里有一个更复杂的例子

也可以在这里查看相关的最佳实践评论

下面的例子展示了如何在兄弟控制器之间传递变量,并在值发生变化时采取行动。

用例示例:在侧栏中有一个过滤器,可以更改另一个视图的内容。

angular.module('myApp', []) .factory('MyService', function() { // private var value = 0; // public return { getValue: function() { return value; }, setValue: function(val) { value = val; } }; }) .controller('Ctrl1', function($scope, $rootScope, MyService) { $scope.update = function() { MyService.setValue($scope.value); $rootScope.$broadcast('increment-value-event'); }; }) .controller('Ctrl2', function($scope, MyService) { $scope.value = MyService.getValue(); $scope.$on('increment-value-event', function() { $scope.value = MyService.getValue(); }); }); <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <div ng-app="myApp"> <h3>Controller 1 Scope</h3> <div ng-controller="Ctrl1"> <input type="text" ng-model="value"/> <button ng-click="update()">Update</button> </div> <hr> <h3>Controller 2 Scope</h3> <div ng-controller="Ctrl2"> Value: {{ value }} </div> </div>

难道不能让属性也成为作用域父对象的一部分吗?

$scope.$parent.property = somevalue;

我不是说它是对的,但它确实有效。

我想通过指出在控制器之间甚至指令之间共享数据的推荐方式是使用服务(工厂)来回答这个问题,正如已经指出的那样,但我也想提供一个工作的实际示例,说明应该如何做到这一点。

下面是工作活塞:http://plnkr.co/edit/Q1VdKJP2tpvqqJL1LF6m?p=info

首先,创建你的服务,它将有你的共享数据:

app.factory('SharedService', function() {
  return {
    sharedObject: {
      value: '',
      value2: ''
    }
  };
});

然后,简单地将它注入到你的控制器上,并在你的作用域上获取共享数据:

app.controller('FirstCtrl', function($scope, SharedService) {
  $scope.model = SharedService.sharedObject;
});

app.controller('SecondCtrl', function($scope, SharedService) {
  $scope.model = SharedService.sharedObject;
});

app.controller('MainCtrl', function($scope, SharedService) {
  $scope.model = SharedService.sharedObject;
});

你也可以为你的指令这样做,它的工作方式是一样的:

app.directive('myDirective',['SharedService', function(SharedService){
  return{
    restrict: 'E',
    link: function(scope){
      scope.model = SharedService.sharedObject;
    },
    template: '<div><input type="text" ng-model="model.value"/></div>'
  }
}]);

希望这个实用而干净的答案能对别人有所帮助。

你可以在服务业或工厂里这样做。除了一些核心差异外,它们本质上是一样的。我在thinkster上找到了这个解释。IO是最容易遵循的。简单、扼要、有效。