AngularJS:如何在控制器之间传递变量?

本文翻译自:AngularJS: How can I pass variables between controllers?

I have two Angular controllers: 我有两个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
}

I can't use Ctrl1 inside Ctrl2 because it is undefined. 我不能使用Ctrl1里面Ctrl2 ,因为它是不确定的。 However if I try to pass it in like so… 但是,如果我尝试像这样传递它…

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

I get an error. 我得到一个错误。 Does anyone know how to do this? 有谁知道如何做到这一点?

Doing 在做

Ctrl2.prototype = new Ctrl1();

Also fails. 也失败。

NOTE: These controllers are not nested inside each other. 注意:这些控制器彼此之间不嵌套。


#1楼

参考:https://stackoom.com/question/oO44/AngularJS-如何在控制器之间传递变量


#2楼

One way to share variables across multiple controllers is to create a service and inject it in any controller where you want to use it. 在多个控制器之间共享变量的一种方法是创建服务并将其注入到要使用它的任何控制器中。

Simple service example: 简单服务示例:

angular.module('myApp', [])
    .service('sharedProperties', function () {
        var property = 'First';

        return {
            getProperty: function () {
                return property;
            },
            setProperty: function(value) {
                property = value;
            }
        };
    });

Using the service in a controller: 在控制器中使用服务:

function Ctrl2($scope, sharedProperties) {
    $scope.prop2 = "Second";
    $scope.both = sharedProperties.getProperty() + $scope.prop2;
}

This is described very nicely in this blog (Lesson 2 and on in particular). 这个博客对此进行了很好的描述(特别是第2课)。

I've found that if you want to bind to these properties across multiple controllers it works better if you bind to an object's property instead of a primitive type (boolean, string, number) to retain the bound reference. 我发现,如果要跨多个控制器绑定到这些属性,则如果绑定到对象的属性而不是原始类型(布尔,字符串,数字)来保留绑定的引用,则效果更好。

Example: var property = { Property1: 'First' }; 示例: var property = { Property1: 'First' }; instead of var property = 'First'; 而不是var property = 'First'; .


UPDATE: To (hopefully) make things more clear here is a fiddle that shows an example of: 更新:为了(希望)使事情变得更清楚, 这是一个小提琴 ,其中显示了以下示例:

  • Binding to static copies of the shared value (in myController1) 绑定到共享值的静态副本(在myController1中)
    • Binding to a primitive (string) 绑定到原语(字符串)
    • Binding to an object's property (saved to a scope variable) 绑定到对象的属性(保存到范围变量)
  • Binding to shared values that update the UI as the values are updated (in myController2) 绑定到在更新值时更新UI的共享值(在myController2中)
    • Binding to a function that returns a primitive (string) 绑定到返回原语(字符串)的函数
    • Binding to the object's property 绑定到对象的属性
    • Two way binding to an object's property 双向绑定到对象的属性

#3楼

If you don't want to make service then you can do like this. 如果您不想提供服务,则可以这样做。

var scope = angular.element("#another ctrl scope element id.").scope();
scope.plean_assign = some_value;

#4楼

Couldn't you also make the property part of the scopes parent? 您是否也可以将该属性作为合并范围的父级?

$scope.$parent.property = somevalue;

I'm not saying it's right but it works. 我并不是说这是正确的,但是可以。


#5楼

--- I know this answer is not for this question, but I want people who reads this question and want to handle Services such as Factories to avoid trouble doing this ---- ---我知道这个答案不是针对这个问题的,但是我希望那些读过这个问题并希望处理诸如工厂之类的服务的人避免这样做的麻烦----

For this you will need to use a Service or a Factory. 为此,您将需要使用服务或工厂。

The services are the BEST PRACTICE to share data between not nested controllers. 这些服务是在非嵌套控制器之间共享数据的最佳实践

A very very good annotation on this topic about data sharing is how to declare objects. 关于数据共享的这个主题的一个很好的注释是如何声明对象。 I was unlucky because I fell in a AngularJS trap before I read about it, and I was very frustrated. 我很不幸,因为在我读到它之前就陷入了AngularJS陷阱,我感到非常沮丧。 So let me help you avoid this trouble. 因此,让我帮助您避免这种麻烦。

I read from the "ng-book: The complete book on AngularJS" that AngularJS ng-models that are created in controllers as bare-data are WRONG! 我从《 ng书:关于AngularJS的完整书》中读到,在控制器中作为裸数据创建的AngularJS ng模型是错误的!

A $scope element should be created like this: $ scope元素应这样创建:

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

And not like this: 而且不是这样的:

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

This is because it is recomended(BEST PRACTICE) for the DOM(html document) to contain the calls as 这是因为建议将DOM(html文档)包含为

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

This is very helpful for nested controllers if you want your child controller to be able to change an object from the parent controller.... 如果希望子控制器能够从父控制器更改对象,这对于嵌套控制器非常有用。

But in your case you don't want nested scopes, but there is a similar aspect to get objects from services to the controllers. 但是在您的情况下,您不需要嵌套作用域,但是有一个相似的方面可以将对象从服务获取到控制器。

Lets say you have your service 'Factory' and in the return space there is an objectA that contains objectB that contains objectC. 假设您拥有服务“工厂”,并且在返回空间中有一个objectA,其中objectB包含objectC。

If from your controller you want to GET the objectC into your scope, is a mistake to say: 如果您想从您的控制器中将objectC放入您的作用域,则错误地说:

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

That wont work... Instead use only one dot. 那行不通...而是只使用一个点。

$scope.neededObjectInController = Factory.ObjectA;

Then, in the DOM you can call objectC from objectA. 然后,在DOM中,您可以从objectA调用objectC。 This is a best practice related to factories, and most important, it will help to avoid unexpected and non-catchable errors. 这是与工厂相关的最佳实践,最重要的是, 它将有助于避免意外的和不可捕获的错误。


#6楼

You could do that with services or factories. 您可以通过服务或工厂来做到这一点。 They are essentially the same apart for some core differences. 它们之间基本相同,只是存在一些核心差异。 I found this explanation on thinkster.io to be the easiest to follow. 我发现thinkster.io上的这种解释最容易理解 Simple, to the point and effective. 简单,要点和有效。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章