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

Javascript AngularJS:如何在控制器之间传递变量?,javascript,angularjs,angularjs-controller,Javascript,Angularjs,Angularjs Controller,我有两个角度控制器: 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 } angular.sharedProperties = angular.sha

我有两个角度控制器:

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
}
angular.sharedProperties = angular.sharedProperties 
    || angular.extend(the-properties-objects);
我不能在
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();
也失败了


注意:这些控制器彼此之间没有嵌套。

跨多个控制器共享变量的一种方法是将变量插入并插入到您想要使用它的任何控制器中

简单服务示例:

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

        return {
            getProperty: function () {
                return property;
            },
            setProperty: function(value) {
                property = value;
            }
        };
    });
function Ctrl2($scope, sharedProperties) {
    $scope.prop2 = "Second";
    $scope.both = sharedProperties.getProperty() + $scope.prop2;
}
在控制器中使用服务:

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

        return {
            getProperty: function () {
                return property;
            },
            setProperty: function(value) {
                property = value;
            }
        };
    });
function Ctrl2($scope, sharedProperties) {
    $scope.prop2 = "Second";
    $scope.both = sharedProperties.getProperty() + $scope.prop2;
}
这在(第2课及以后的课程)中有很好的描述

我发现,如果要跨多个控制器绑定到这些属性,最好绑定到对象的属性而不是基元类型(布尔、字符串、数字)以保留绑定引用

示例:
var property={Property1:'First'}而不是
var属性='First'


更新:以(希望)更清楚地说明以下内容:

  • 绑定到共享值的静态副本(在myController1中)
    • 绑定到基元(字符串)
    • 绑定到对象的属性(保存到范围变量)
  • 绑定到在值更新时更新UI的共享值(在myController2中)
    • 绑定到返回基元(字符串)的函数
    • 绑定到对象的属性
    • 对象属性的双向绑定

    • 如果你不想提供服务,那么你可以这样做

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

      您不能也使属性成为作用域父级的一部分吗

      $scope.$parent.property = somevalue;
      
      我不是说这是对的,但它是有效的。

      --我知道这个答案不是针对这个问题的,但我希望阅读这个问题并希望处理工厂等服务的人避免麻烦--

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

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

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

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

      $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';
        };
      });
      
      不是这样的:

      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.
      
      那不行… 相反,只使用一个点

      $scope.neededObjectInController = Factory.ObjectA;
      

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

      您可以通过服务或工厂来做到这一点。它们本质上是相同的,只是存在一些核心差异。我发现这个解释是最容易理解的。简单、中肯、有效。

      上面的示例非常有效。我只是做了一个修改,以防我需要管理多个值。我希望这有帮助

      app.service('sharedProperties', function () {
      
          var hashtable = {};
      
          return {
              setValue: function (key, value) {
                  hashtable[key] = value;
              },
              getValue: function (key) {
                  return hashtable[key];
              }
          }
      });
      

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

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

      
      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;
      });
      
      
      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;
      });
      

      下面是一个非常简单的
      工厂
      示例:

      
      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;
      });
      
      
      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;
      });
      


      如果这太简单了


      另外

      不创建服务的解决方案,使用$rootScope:

      angular.module('myApp', [])
          .service('sharedProperties', function () {
              var property = 'First';
      
              return {
                  getProperty: function () {
                      return property;
                  },
                  setProperty: function(value) {
                      property = value;
                  }
              };
          });
      
      function Ctrl2($scope, sharedProperties) {
          $scope.prop2 = "Second";
          $scope.both = sharedProperties.getProperty() + $scope.prop2;
      }
      
      要在应用程序控制器之间共享属性,可以使用Angular$rootScope。这是共享数据的另一种选择,可以让人们了解数据

      跨控制器共享某些功能的首选方法是服务,可以使用$rootscope读取或更改全局属性

      var app = angular.module('mymodule',[]);
      app.controller('Ctrl1', ['$scope','$rootScope',
        function($scope, $rootScope) {
          $rootScope.showBanner = true;
      }]);
      
      app.controller('Ctrl2', ['$scope','$rootScope',
        function($scope, $rootScope) {
          $rootScope.showBanner = false;
      }]);
      
      在模板中使用$rootScope(使用$root访问属性):


      啊,有一点这种新东西作为另一种选择。它是本地存储,在angular工作的地方工作。不客气。(但真的,谢谢那家伙)

      定义默认值:

      $scope.$storage = $localStorage.$default({
          prop1: 'First',
          prop2: 'Second'
      });
      
      访问以下值:

      $scope.prop1 = $localStorage.prop1;
      $scope.prop2 = $localStorage.prop2;
      
      存储值

      $localStorage.prop1 = $scope.prop1;
      $localStorage.prop2 = $scope.prop2;
      

      请记住在应用程序中注入ngStorage,在控制器中注入$localStorage。

      我想指出,在控制器之间共享数据甚至指令的推荐方法是使用已经指出的服务(工厂),但我也想提供一个实用的例子,说明如何做到这一点

      这是正在工作的插销:

      首先,创建您的服务,让您的共享数据

      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>'
        }
      }]);
      
      app.directive('myDirective',['SharedService',function(SharedService){
      返回{
      限制:'E',
      链接:功能(范围){
      scope.model=SharedService.sharedObject;
      },
      模板:“”
      }
      }]);
      

      希望这个实用且清晰的答案能对其他人有所帮助。

      除了$rootScope和services之外,还有一个清晰且简单的替代解决方案可以扩展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
      }
      
      angular.sharedProperties = angular.sharedProperties 
          || angular.extend(the-properties-objects);
      
      此属性属于“angular”对象,与作用域分开,可以在作用域和服务中共享


      它的一个好处是,您不必注入对象:在定义之后,可以立即在任何地方访问对象

      有两种方法可以做到这一点

      1) 使用get/set服务

      (二)
      $scope.$emit('key',{data:value})//要设置值

       $rootScope.$on('key', function (event, data) {}); // to get the value
      

      我倾向于使用价值观,为任何人高兴