在Angular JS中的控制器之间传递数据?

我有一个基本的控制器,显示我的产品,

App.controller('ProductCtrl',function($scope,$productFactory){ $productFactory.get().success(function(data){ $scope.products = data; }); }); 

在我看来,我在列表中显示这个产品

 <ul> <li ng-repeat="product as products"> {{product.name}} </li> </ul 

我想要做的是当有人点击产品名称,我有另一个名为购物车这个产品被添加的视图。

  <ul class="cart"> <li> //click one added here </li> <li> //click two added here </li> </ul> 

所以我的疑问是,如何将这个点击的产品从第一个控制器传递到第二个? 我认为购物车也应该是一个控制器。

我使用指令处理单击事件。 另外我觉得我应该使用服务来实现上述function只是无法形象如何? 因为购物车将预定义数量的产品可能是5/10取决于用户是哪一页。 所以我想保持这个通用。

更新:

我创build了一个服务来广播,并在第二个控制器我收到它。 现在查询是如何更新dom? 由于我的产品清单非常硬编码。

从描述来看,好像你应该使用一个服务。 查看http://egghead.io/lessons/angularjs-sharing-data-between-controllers和AngularJS服务在控制器之间传递数据以查看一些示例。;

你可以这样定义你的产品服务:

 app.service('productService', function() { var productList = []; var addProduct = function(newObj) { productList.push(newObj); }; var getProducts = function(){ return productList; }; return { addProduct: addProduct, getProducts: getProducts }; }); 

dependency injection服务到两个控制器。

在您的ProductController ,定义一些将所选对象添加到数组的操作:

 app.controller('ProductController', function($scope, productService) { $scope.callToAddToProductList = function(currObj){ productService.addProduct(currObj); }; }); 

在您的CartController ,从服务中获取产品:

 app.controller('CartController', function($scope, productService) { $scope.products = productService.getProducts(); }); 

如何将这个点击的产品从第一个控制器传递到第二个?

点击可以调用调用广播的方法:

 $rootScope.$broadcast('SOME_TAG', 'your value'); 

第二个控制器会听这个标签,如:

 $scope.$on('SOME_TAG', function(response) { // .... }) 

由于我们不能将$ scope注入到服务中,所以没有任何东西像$ single作用域。

但是我们可以注入$rootScope 。 因此,如果您将值存储到服务中,则可以运行$rootScope.$broadcast('SOME_TAG', 'your value'); 在服务机构。 (请参阅有关服务的@Charx描述)

 app.service('productService', function($rootScope) {/*....*/} 

请检查有关 $广播 , $发射的 好文章

解决scheme无需创build服务,使用$ rootScope:

要跨应用程序控制器共享属性,您可以使用Angular $ rootScope。 这是分享数据的另一种select,让人们知道这一点。

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

 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的访问属性):

 <div ng-controller="Ctrl1"> <div class="banner" ng-show="$root.showBanner"> </div> </div> 

你可以通过两种方法做到这一点。

  1. 通过使用$rootscope ,但我不推荐这个。 $rootScope是最顶级的范围。 应用程序只能有一个$rootScope ,它将在应用程序的所有组件之间共享。 因此,它就像一个全局variables。

  2. 使用服务。 您可以通过在两个控制器之间共享服务来完成此操作。 代码服务可能如下所示:

     app.service('shareDataService', function() { var myList = []; var addList = function(newObj) { myList.push(newObj); } var getList = function(){ return myList; } return { addList: addList, getList: getList }; }); 

    你可以在这里看到我的小提琴。

在控制器之间共享数据的更简单的方法是使用嵌套的数据结构。 例如,而不是

 $scope.customer = {}; 

我们可以用

 $scope.data = { customer: {} }; 

data属性将从父范围inheritance,所以我们可以覆盖它的字段,保持来自其他控制器的访问。

 angular.module('testAppControllers', []) .controller('ctrlOne', function ($scope) { $scope.$broadcast('test'); }) .controller('ctrlTwo', function ($scope) { $scope.$on('test', function() { }); }); 

我们可以在会话中存储数据,并可以在程序中的任何地方使用它。

 $window.sessionStorage.setItem("Mydata",data); 

其他地方

 $scope.data = $window.sessionStorage.getItem("Mydata"); 

我创build了一个控制pathpath模式之间共享范围的工厂,所以当用户在相同的path父path中导航时,可以维护共享数据。

 .controller('CadastroController', ['$scope', 'RouteSharedScope', function($scope, routeSharedScope) { var customerScope = routeSharedScope.scopeFor('/Customer'); //var indexScope = routeSharedScope.scopeFor('/'); } ]) 

因此,如果用户转到另一个pathpath,例如“/ Support”,path“/ Customer”的共享数据将被自动销毁。 但是,如果不是这个用户转到“子”path,比如“/ Customer / 1”或“/ Customer / list”,范围将不会被销毁。

你可以在这里看到一个例子: http : //plnkr.co/edit/OL8of9

我在这里看到了答案,它正在回答在控制器之间共享数据的问题,但是如果我希望一个控制器通知另一个控制器数据已被更改(不使用广播),我该怎么办? 简单! 只使用着名的访客模式:

 myApp.service('myService', function() { var visitors = []; var registerVisitor = function (visitor) { visitors.push(visitor); } var notifyAll = function() { for (var index = 0; index < visitors.length; ++index) visitors[index].visit(); } var myData = ["some", "list", "of", "data"]; var setData = function (newData) { myData = newData; notifyAll(); } var getData = function () { return myData; } return { registerVisitor: registerVisitor, setData: setData, getData: getData }; } myApp.controller('firstController', ['$scope', 'myService', function firstController($scope, myService) { var setData = function (data) { myService.setData(data); } } ]); myApp.controller('secondController', ['$scope', 'myService', function secondController($scope, myService) { myService.registerVisitor(this); this.visit = function () { $scope.data = myService.getData(); } $scope.data = myService.getData(); } ]); 

以这种简单的方式,一个控制器可以更新另一个控制器的一些数据已被更新。

在你的模块中创build一个工厂,并在控制器中添加工厂的引用,并在控制器中使用它的variables,现在通过添加引用来获取其他控制器中的数据值

我不知道是否会帮助任何人,但基于Charx(谢谢!)回答我已经创build了简单的caching服务。 随意使用,混合和分享:

 angular.service('cache', function() { var _cache, _store, _get, _set, _clear; _cache = {}; _store = function(data) { angular.merge(_cache, data); }; _set = function(data) { _cache = angular.extend({}, data); }; _get = function(key) { if(key == null) { return _cache; } else { return _cache[key]; } }; _clear = function() { _cache = {}; }; return { get: _get, set: _set, store: _store, clear: _clear }; }); 

一种使用angular度服务的方法:

 var app = angular.module("home", []); app.controller('one', function($scope, ser1){ $scope.inputText = ser1; }); app.controller('two',function($scope, ser1){ $scope.inputTextTwo = ser1; }); app.factory('ser1', function(){ return {o: ''}; }); <div ng-app='home'> <div ng-controller='one'> Type in text: <input type='text' ng-model="inputText.o"/> </div> <br /> <div ng-controller='two'> Type in text: <input type='text' ng-model="inputTextTwo.o"/> </div> </div> 

https://jsfiddle.net/1w64222q/

FYI $ scope对象具有$ emit,$ broadcast,$和$ $ rootScope对象具有相同的$ emit,$ broadcast,$ on

在这里阅读有关发布/订阅devise模式的更多信息

有三种方法可以做到这一点,

a)使用服务

b)利用控制器范围之间的父母/子女关系。

c)在Angular 2.0中,“As”关键字将把数据从一个控制器传递到另一个控制器。

有关示例的更多信息,请查看以下链接:

http://www.learnit.net.in/2016/03/angular-js.html

为了改善@Maxim使用$ broadcast提出的解决scheme,发送数据不会改变

 $rootScope.$broadcast('SOME_TAG', 'my variable'); 

而是收听数据

 $scope.$on('SOME_TAG', function(event, args) { console.log("My variable is", args);// args is value of your variable }) 
 var custApp = angular.module("custApp", []) .controller('FirstController', FirstController) .controller('SecondController',SecondController) .service('sharedData', SharedData); FirstController.$inject = ['sharedData']; function FirstController(sharedData) { this.data = sharedData.data; } SecondController.$inject['sharedData']; function SecondController(sharedData) { this.data = sharedData.data; } function SharedData() { this.data = { value: 'default Value' } } 

第一控制器

 <div ng-controller="FirstController as vm"> <input type=text ng-model="vm.data.value" /> </div> 

第二控制器

  <div ng-controller="SecondController as vm"> Second Controller<br> {{vm.data.value}} </div> 

1

 using $localStorage app.controller('ProductController', function($scope, $localStorage) { $scope.setSelectedProduct = function(selectedObj){ $localStorage.selectedObj= selectedObj; }; }); app.controller('CartController', function($scope,$localStorage) { $scope.selectedProducts = $localStorage.selectedObj; $localStorage.$reset();//to remove }); 

2

点击可以调用调用广播的方法:

 $rootScope.$broadcast('SOME_TAG', 'your value'); and the second controller will listen on this tag like: $scope.$on('SOME_TAG', function(response) { // .... }) 

3

 using $rootScope: 

4

 window.sessionStorage.setItem("Mydata",data); $scope.data = $window.sessionStorage.getItem("Mydata"); 

一种使用angular度服务的方法:

 var app = angular.module("home", []); app.controller('one', function($scope, ser1){ $scope.inputText = ser1; }); app.controller('two',function($scope, ser1){ $scope.inputTextTwo = ser1; }); app.factory('ser1', function(){ return {o: ''}; }); 

我觉得

最好的办法

是使用$ localStorage。 (一直工作)

 app.controller('ProductController', function($scope, $localStorage) { $scope.setSelectedProduct = function(selectedObj){ $localStorage.selectedObj= selectedObj; }; }); 

你的cardController会

 app.controller('CartController', function($scope,$localStorage) { $scope.selectedProducts = $localStorage.selectedObj; $localStorage.$reset();//to remove }); 

你也可以添加

 if($localStorage.selectedObj){ $scope.selectedProducts = $localStorage.selectedObj; }else{ //redirect to select product using $location.url('/select-product') }