我正在尝试跨控制器共享数据。用例是一种多步骤形式,在一个输入中输入的数据稍后将用于原始控制器之外的多个显示位置。下面和jsfiddle中的代码。
HTML
<div ng-controller="FirstCtrl">
<input type="text" ng-model="FirstName"><!-- Input entered here -->
<br>Input is : <strong>{{FirstName}}</strong><!-- Successfully updates here -->
</div>
<hr>
<div ng-controller="SecondCtrl">
Input should also be here: {{FirstName}}<!-- How do I automatically updated it here? -->
</div>
JS
// declare the app with no dependencies
var myApp = angular.module('myApp', []);
// make a factory to share data between controllers
myApp.factory('Data', function(){
// I know this doesn't work, but what will?
var FirstName = '';
return FirstName;
});
// Step 1 Controller
myApp.controller('FirstCtrl', function( $scope, Data ){
});
// Step 2 Controller
myApp.controller('SecondCtrl', function( $scope, Data ){
$scope.FirstName = Data.FirstName;
});
任何帮助都非常感激。
有多种方法可以在控制器之间共享数据
角服务
$broadcast, $emit方法
父到子控制器通信
rootscope美元
众所周知,$rootscope不是数据传输或通信的首选方式,因为它是一个全局作用域,可用于整个应用程序
对于Angular Js控制器之间的数据共享,Angular服务是最佳实践,例如.factory, .service
供参考
如果数据从父控制器传输到子控制器,您可以通过$scope直接访问子控制器中的父数据
如果你正在使用ui-router,那么你可以使用$stateParmas来传递url参数,如id,名称,键等
$broadcast也是在控制器之间从父控制器传输数据到子控制器的好方法,$emit是将数据从子控制器传输到父控制器的好方法
HTML
<div ng-controller="FirstCtrl">
<input type="text" ng-model="FirstName">
<br>Input is : <strong>{{FirstName}}</strong>
</div>
<hr>
<div ng-controller="SecondCtrl">
Input should also be here: {{FirstName}}
</div>
JS
myApp.controller('FirstCtrl', function( $rootScope, Data ){
$rootScope.$broadcast('myData', {'FirstName': 'Peter'})
});
myApp.controller('SecondCtrl', function( $rootScope, Data ){
$rootScope.$on('myData', function(event, data) {
$scope.FirstName = data;
console.log(data); // Check in console how data is coming
});
});
参考给出的链接了解更多关于$broadcast的信息
有多种方法可以做到这一点。
事件——已经解释得很好了。
UI路由器-上面解释了。
Service -使用上面显示的更新方法
坏——注意变化。
另一种父-子方法而不是发射和广播-
*
<superhero flight speed strength> Superman is here! </superhero>
<superhero speed> Flash is here! </superhero>
*
app.directive('superhero', function(){
return {
restrict: 'E',
scope:{}, // IMPORTANT - to make the scope isolated else we will pollute it in case of a multiple components.
controller: function($scope){
$scope.abilities = [];
this.addStrength = function(){
$scope.abilities.push("strength");
}
this.addSpeed = function(){
$scope.abilities.push("speed");
}
this.addFlight = function(){
$scope.abilities.push("flight");
}
},
link: function(scope, element, attrs){
element.addClass('button');
element.on('mouseenter', function(){
console.log(scope.abilities);
})
}
}
});
app.directive('strength', function(){
return{
require:'superhero',
link: function(scope, element, attrs, superHeroCtrl){
superHeroCtrl.addStrength();
}
}
});
app.directive('speed', function(){
return{
require:'superhero',
link: function(scope, element, attrs, superHeroCtrl){
superHeroCtrl.addSpeed();
}
}
});
app.directive('flight', function(){
return{
require:'superhero',
link: function(scope, element, attrs, superHeroCtrl){
superHeroCtrl.addFlight();
}
}
});
我已经创建了一个工厂来控制路由路径模式之间的共享作用域,因此您可以在用户在相同的路由父路径中导航时维护共享数据。
.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
有许多方法可以在控制器之间共享数据
使用服务
使用美元的状态。去服务
使用stateparams
使用rootscope
各方法说明:
I am not going to explain as its already explained by someone
using $state.go
$state.go('book.name', {Name: 'XYZ'});
// then get parameter out of URL
$state.params.Name;
$stateparam works in a similar way to $state.go, you pass it as object from sender controller and collect in receiver controller using stateparam
using $rootscope
(a) sending data from child to parent controller
$scope.Save(Obj,function(data) {
$scope.$emit('savedata',data);
//pass the data as the second parameter
});
$scope.$on('savedata',function(event,data) {
//receive the data as second parameter
});
(b) sending data from parent to child controller
$scope.SaveDB(Obj,function(data){
$scope.$broadcast('savedata',data);
});
$scope.SaveDB(Obj,function(data){`enter code here`
$rootScope.$broadcast('saveCallback',data);
});
正如@MaNn在接受的答案的一个评论中指出的那样,如果页面被刷新,解决方案将无法工作。
解决方案是使用localStorage或sessionStorage来临时持久化希望跨控制器共享的数据。
Either you make a sessionService whose GET and SET method, encrypts and decrypts the data and reads the data from either localStorage or sessionStorage. So now you use this service directly to read and write the data in the storage via any controller or service you want. This is a open approach and easy one
Else you make a DataSharing Service and use localStorage inside it - so that if the page is refreshed the service will try and check the storage and reply back via the Getters and Setters you have made public or private in this service file.
只需简单地执行(在v1.3.15中测试):
<article ng-controller="ctrl1 as c1">
<label>Change name here:</label>
<input ng-model="c1.sData.name" />
<h1>Control 1: {{c1.sData.name}}, {{c1.sData.age}}</h1>
</article>
<article ng-controller="ctrl2 as c2">
<label>Change age here:</label>
<input ng-model="c2.sData.age" />
<h1>Control 2: {{c2.sData.name}}, {{c2.sData.age}}</h1>
</article>
<script>
var app = angular.module("MyApp", []);
var dummy = {name: "Joe", age: 25};
app.controller("ctrl1", function () {
this.sData = dummy;
});
app.controller("ctrl2", function () {
this.sData = dummy;
});
</script>