在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>

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

我处理点击事件使用指令。我也觉得我应该使用服务来实现上述功能,只是不明白如何?因为购物车将被预定义的产品数量添加可能是5/10取决于哪个页面的用户。所以我想保持它的一般性。

更新:

我创建了一个广播服务,在第二个控制器我接收它。现在的问题是如何更新dom?因为我的产品清单是硬编码的。

356983 次浏览

如何通过这个点击产品从第一个控制器到第二个?

在单击时,可以调用调用广播的方法:

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

第二个控制器会监听这个标签,像这样:

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

因为我们不能将$scope注入到服务中,所以没有什么东西可以像单一的$scope一样。

但是我们可以注入$rootScope。因此,如果你在服务中存储值,你可以在服务体中运行$rootScope.$broadcast('SOME_TAG', 'your value');。(参见@Charx服务描述)

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

__abc0 __abc1, __abc2

从描述来看,似乎您应该使用服务。查看http://egghead.io/lessons/angularjs-sharing-data-between-controllersAngularJS服务在控制器之间传递数据来查看一些例子。

你可以这样定义你的产品服务(作为一个工厂):

app.factory('productService', function() {
var productList = [];


var addProduct = function(newObj) {
productList.push(newObj);
};


var getProducts = function(){
return productList;
};


return {
addProduct: addProduct,
getProducts: getProducts
};


});

依赖项将服务注入到两个控制器中。

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:

要跨应用控制器共享属性,你可以使用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访问属性):

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

我已经创建了一个工厂来控制路由路径模式之间的共享作用域,因此您可以在用户在相同的路由父路径中导航时维护共享数据。

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

因此,如果用户转到另一个路由路径,例如'/Support',路径'/Customer'的共享数据将被自动销毁。但是,如果用户去到“子”路径,比如“/Customer/1”或“/Customer/list”,作用域不会被销毁。

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

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

$scope.customer = {};

我们可以用

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

data属性将从父作用域继承,因此我们可以覆盖它的字段,保持来自其他控制器的访问。

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

  1. 通过使用$rootscope,但我不建议这样做。$rootScope是最顶层的作用域。一个应用程序只能有一个$rootScope 在应用程序的所有组件之间共享。因此,它就像一个 李全局变量。< / p > < / >

  2. < p >使用服务。您可以通过在两个控制器之间共享服务来实现这一点。服务的代码可能是这样的:

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

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

我在这里看到了答案,它回答了控制器之间共享数据的问题,但是如果我想让一个控制器通知另一个控制器数据已经更改的事实(不使用广播),我应该怎么做?简单!使用著名的访客模式:

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

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

< p >供参考 $scope对象有$emit, $broadcast, $on 和 $rootScope对象在

上有相同的$emit, $broadcast, $

在angular 在这里中阅读更多关于发布/订阅设计模式的信息

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

有三种方法,

A)使用服务

b)利用控制器作用域间依赖的父/子关系。

c)在Angular 2.0 "As"关键字将数据从一个控制器传递到另一个控制器。

如需更多信息,请查看以下链接:

http://www.tutorial-points.com/2016/03/angular-js.html

在你的模块中创建一个工厂,并在控制器中添加一个工厂的引用,并在控制器中使用它的变量,现在通过在任何你想要的地方添加引用来获得另一个控制器中的数据值

我不知道它是否会帮助任何人,但基于Charx(谢谢!)的回答,我创建了简单的缓存服务。请随意使用、混音和分享:

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

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

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

其他地方

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

使用angular service的一种方法是:

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/

为了改进@Maxim提出的使用$broadcast的解决方案,发送数据不改变

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

我认为

最好的方法

是使用$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')
}
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'
}
}

第一个控制器< br >

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

5

使用angular service的一种方法是:

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