我有一个角度应用程序,页面上有2个部分。
1部分是侧栏,给出了一个概要。让我们说:
Players 5 // {{ numOfPlayers }}
代码是一个ajax调用。我不想增加,因为这个号码可以通过另一个呼叫增加。我需要在获取数组长度后运行ajax调用。
angular.module('app').controller('nav', function($scope,$http) {
$http.get('/players').then(function(data) {
$scope.numOfPlayers = data.players.length;
});
});
现在位于主页面上的完全独立的控制器中。用户可以添加播放器。我如何拥有它以便我可以更新导航控制器?
angular.module('app').controller('mainController', function($scope,$http) {
$http.post(.....).then(function(data) {
//update the numOfPlayers so the nav is updated.
});
});
答案 0 :(得分:5)
您可以使用服务来保存共享数据和$watch
更改:
var app = angular.module('TestApp', []);
app.service("playersService", function () {
this.numOfPlayers = 0;
});
app.controller("navController", function ($scope, $http, playersService) {
// Update the shared resource initial value with GET result
// $http.get('/players').then(function(data) {
// playersService.numOfPlayers = response.data.length;
// });
playersService.numOfPlayers = 0;
$scope.$watch(function () { return playersService.numOfPlayers; }, function (value) {
$scope.numOfPlayers = value;
});
});
app.controller("mainController", function ($scope, playersService) {
$scope.addPlayer = function () {
// POST and update the shared resource with result
// $http.post(.....).then(function(data) {
playersService.numOfPlayers++;
}
});

<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="TestApp">
<section ng-controller="navController">
<h1>Nav</h1>
Players {{ numOfPlayers }}
</section>
<section ng-controller="mainController">
<h1>Main</h1>
<button ng-click="addPlayer()">
Add player
</button>
</section>
</div>
&#13;
您可以使用父控制器(比如pageController)来保存共享数据:
var app = angular.module('TestApp', []);
app.controller("pageController", function ($scope) {
$scope.numOfPlayers = null;
});
app.controller("mainController", function ($scope, $http) {
$scope.addPlayer = function () {
// POST and update the shared resource with result
// $http.post(.....).then(function(data) {
$scope.$parent.numOfPlayers++;
};
});
app.controller("navController", function ($scope, $http) {
// Update the shared resource initial value with GET result
// $http.get('/players').then(function(data) {
// $scope.$parent.numOfPlayers = response.data.length;
// });
$scope.$parent.numOfPlayers = 0;
});
&#13;
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app="TestApp" ng-controller="pageController">
<section ng-controller="navController">
<h1>Nav</h1>
Players {{ numOfPlayers }}
</section>
<section ng-controller="mainController">
<h1>Main</h1>
<button ng-click="addPlayer()">
Add player
</button>
</section>
</div>
&#13;
旁注:
两种方法:
最好将播放器阵列用作共享资源。在这个例子中,我试图保持简单。
最好更新mainController
的初始资源值,而不是navController
。在示例中,我尝试与您的代码保持一致。
答案 1 :(得分:4)
首先,我建议使用最佳实践并使用组件而不是ng-controller。
所以你有两个组成部分:
angular.module('app').component('nav', {});
和
angular.module('app').component('main', {});
现在,您可以通过服务:
在它们之间共享州数据angular.module('app').service('PlayersService', function(){
this.players = [];
this.getAll() = () => {};
this.add(player) = () => {};
});
只有一个棘手的部分是你需要观看所有组件玩家更改:
angular.module('app').component('nav', {
controller: function($scope, PlayersService){
PlayersService.getAll();
$scope.$watch(() => PlayersService.players.length, (playersLength) => this.numOfPlayers = playersLength)
}
});
angular.module('app').component('main', {
controller: function($scope, PlayersService){
//PlayersService.add(player);
$scope.$watch(() => PlayersService.players.length, (playersLength) => this.numOfPlayers = playersLength)
}
});
因此,在这两种情况下,范围属性 numOfPlayers 都会更新。
答案 2 :(得分:2)
由于您在一个页面上有两个部分,我的建议是使用一个或多个组件而不是单独的控制器。示例如下:
angular
.module('exampleApp', [])
.controller('ExampleController', ExampleController);
function ExampleController() {
var vm = this;
vm.numPlayers = 0;
}
angular
.module('exampleApp')
.component('playerSummary', {
bindings: {
numPlayers: '<'
},
template: `<p>{{ $ctrl.numPlayers }}</p>`
});
angular
.module('exampleApp')
.component('playerAddition', {
bindings: {
numPlayers: '='
},
controller: function() {
function addPlayer() {
this.numPlayers++;
}
this.addPlayer = addPlayer;
},
template: `<button type="button" ng-click="$ctrl.addPlayer()">+</button>`
});
&#13;
<!DOCTYPE html>
<html ng-app='exampleApp'>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular.min.js"></script>
</head>
<body ng-controller="ExampleController as vm">
<player-summary num-players="vm.numPlayers"></player-summary>
<player-addition num-players="vm.numPlayers"></player-addition>
</body>
</html>
&#13;
不推荐,但您也可以使用$ rootScope或catch并发出事件。
您还可以绑定到服务属性,例如下面的示例,或直接绑定到服务。
angular
.module('exampleApp', []);
angular
.module('exampleApp')
.controller('FirstController', FirstController);
function FirstController(PlayerService) {
var vm = this;
vm.players = PlayerService.players;
}
FirstController.$inject = ['PlayerService'];
angular
.module('exampleApp')
.controller('SecondController', SecondController);
function SecondController(PlayerService) {
var vm = this;
vm.addPlayer = function() {
PlayerService.addPlayer();
}
}
SecondController.$inject = ['PlayerService'];
angular
.module('exampleApp')
.service('PlayerService', PlayerService);
function PlayerService() {
var PlayerService = this;
PlayerService.players = [];
PlayerService.addPlayer = function() {
PlayerService.players.push({});
}
}
&#13;
<!DOCTYPE html>
<html ng-app='exampleApp'>
<head>
<script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.5.5/angular.min.js"></script>
</head>
<body>
<div ng-controller="FirstController as vm">
<p>{{vm.players.length}}</p>
</div>
<div ng-controller="SecondController as vm">
<button ng-click="vm.addPlayer()">+</button>
</div>
</body>
</html>
&#13;
正如Khalil Malki所说,您可以观看服务价值
正如Jaqen H&#39; ghar所提到的,你可以使用父控制器。
答案 3 :(得分:1)
您可以使用angular.factory()
或angular.service(); or $localStorage and or $sessionStorage
。
首先进行全局调用,而不是在控制器内调用:
示例:强>
angular.factory('updateVal', function(){
var data;
return {
getPlayers: function(){
return $http.get('/players').success(function(results){
data = results;
return data;
});
},
setPlayers: function(val){
if(val){
data = val;
return data;
}
else {
return data;
}
}
}
});
在你的控制器中: 第一个控制器
angular.module('app').controller('nav', function($scope,updateVal){
$scope.numOfPlayers = updateVal.getPlayers();
$scope.$watch(function(){
return updateVal.setPlayers().length > 0;
}, function(){
$scope.numOfPlayers = updateVal.setPlayers();
})
})
第二控制器:
angular.module('app').controller('mainController', function($scope,$http,updateVal) {
// this function update the players updateVal.getPlayers();
$http.post(.....).then(function(data) {
//update the numOfPlayers so the nav is updated.
// after posting call this function:
updateVal.setPlayers(data);
});
});
使用angular.service:
可以这样做:
angular.service('updatePlayers', function(){
var updatedPlayers;
this.setPlayers = function(args){
updatedPlayers = args;
}
this.getPlayers = function(){
return updatedPlayers;
}
})
在您的第一个控制器中:
angular.module('app').controller('nav', function($scope,$http,updatePlayers) {
$http.get('/players').then(function(data) {
updatePlayers.setPlayers(data.players.length);
$scope.numOfPlayers = data.players.length;
});
});
在第二个控制器中:
angular.module('app').controller('mainController', function($scope,$http,updatePlayers) {
$http.post(.....).then(function(data) {
//update the numOfPlayers so the nav is updated.
updatePlayers.getPlayers();
});
});
已修改以修复拼写错误
答案 4 :(得分:1)
更好的方法是两个有两个指令:
page
指令nav
指令 nav
指令会将一些数据作为输入。在这种情况下,玩家的数量可以是输入之一。然后,当您将nav
指令嵌套在page
指令中时,您可以将数据从page
传递到nav
,而nav
会自动更新价值变化:
<强> HTML 强>
<page></page>
<强>的JavaScript 强>
app.directive('page', function() {
return {
restrict: 'E',
controller: function($scope, playerSvc) {
playerSvc.getPlayers.then(function(resp) {
$scope.players = resp.data;
});
},
template: '<header> blah</header> <nav player-count="players.length"></nav> <footer></footer>'
};
});
app.directive('nav', function() {
return {
restrict: 'E',
scope: { playerCount: '=' },
template: '<div> player count: {{playerCount}} </div>'
};
});
通过这样做,您可以隔离指令(组件)并创建清晰的边界。每个组件或指令都有一个小的责任。在这种情况下,nav
获取一些数据并显示它们,并且还负责导航。 page
指令为页面上的不同组件或指令提供全局数据。您可以使用相同的想法并决定谁将玩家添加到玩家列表中。因为nav
指令与players.length
相关联,所以players
更新后会自动更新。
答案 5 :(得分:1)
可能会调用nav控制器中的方法,以便范围变量更新,最终通过双向绑定更新视图
angular.module('app').controller('nav', function($scope,$http) {
$rootScope.$on("CallMethodNavController", function(){
$scope.navMethod();
});
$scope.CallMethodNavController=function(){
$http.get('/players').then(function(data) {
$scope.numOfPlayers = data.players.length;
}
});
});
然后在第二个控制器中,一旦添加了一个玩家,你就会调用这个方法:
$rootScope.$emit("CallMethodNavController", {});
答案 6 :(得分:1)
无需为此创建手表或活动。
使用服务在整个应用中获取,存储,更新和分享玩家阵列。
而不是创建长度的原始变量...存储对控制器和视图中数组的引用做{{players.length}}
并让角度视图观察者负责更新。
angular.module('app').factory('playersService', function($http){
// now have an array to share across app
// and reference to addPlayer function
var factory ={players:[], addPlayer: addPlayer };
// load the players and add them to array
$http.get('/players').then(function(response) {
Array.prototype.push.apply(factory.players, response.data);
});
function addPlayer(player){
return $http.post(url, player).then(function(resp){
// add new player to shared array
factor.push(resp.data);
}
}
return factory;
});
导航控制器
angular.module('app').controller('nav', function($scope,playersService) {
$scope.players = playersService.players; // store full array reference
});
导航视图
Number Players: {{players.length}} <!-- angular will automatically watch and update -->
其他控制器
angular.module('app').controller('mainController', function($scope,playersService) {
$scope.newPlayer={};// bind to ng-model's in form
$scope.saveNewPlayer = function(){
playersService.addPlayer($scope.newPlayer).then(function(){
alert('Number of players in nav will already be updted');
// clear form
$scope.newPlayer={};
})
});
});
答案 7 :(得分:1)
使用$ emit和$ on 从主cintroller $ rootScope。$ broadcast(&#39; update&#39;,&#39; status&#39;){$ http.post(.....)。then(function(data){ //更新numOfPlayers以更新导航。 });}
and in your nav controller use
$scope.$on('eventName', function (event, args) { $http.get('/players').then(function(data) {
$scope.numOfPlayers = data.players.length;});});
$ broadcast从父节点传送到子节点,因此父控制器中的任何更改都将反映在子控制器
中