在 OnsenUI+AngularJS+PhoneGap 中的控制器之间传递数据
Passing data between controllers in OnsenUI+AngularJS+PhoneGap
我发现有人问和回答了与我类似的问题,但我认为我的情况有所不同。我从这里的示例代码开始 enter link description here 一个简单的应用程序,它有一个使用 Google 地图的滑动菜单。
我正在创建一个原型,让用户提交新项目,这些新项目被添加到待定项目列表中,然后添加到地图中。我现在专注于第一部分——让用户创建项目,并自动更新待提交列表。然后我添加了一个简单的表单来创建新项目:
<ons-page>
<ons-toolbar fixed-style ng-controller="SlidingMenuController">
<div class="left">
<ons-toolbar-button ng-click="slidingMenu.toggleMenu()"><ons-icon icon="bars"></ons-icon></ons-toolbar-button>
</div>
<div class="center">New Submission</div>
</ons-toolbar>
<ons-row style="margin-top: 10px; text-align: center;">
<ons-col ng-controller="NewSubmissionController">
<p style="font-size: 12px;">Please insert a brief description of your find and its material.</p>
<textarea style="width: 97%;" id="subDescrText" class="textarea" rows="4" placeholder="Type your description here..." value="" ng-model="subDescription"></textarea>
<ons-button style="margin-top: 24px;" ng-click="doStore()">
Store
</ons-button>
</ons-col>
</ons-row>
</ons-page>
另一个页面列出了创建的提交:
<ons-page>
<ons-toolbar>
<div class="left">
<ons-toolbar-button ng-click="slidingMenu.toggleMenu()"><ons-icon icon="bars"></ons-icon></ons-toolbar-button>
</div>
<div class="center">Pending Submissions</div>
</ons-toolbar>
<div style="text-align: center;">
<ons-list id="pendingList" var="aPendingList" ng-controller="PendingListController">
<ons-list-item ng-repeat="pi in pendingItems">
<p>{{pi.description}}</p>
<span>{{pi.material}}</span>
</ons-list-item>
</ons-list>
</div>div>
<p style="margin-top: 12px; text-align: center; width: 100%;" >
<ons-button ng-click="">
Upload All
</ons-button>
</p>
</ons-page>
然后我添加了这些控制器:
app.controller('NewSubmissionController', function($scope) {
$scope.selMat;
$scope.subDescription;
$scope.doStore = function() {
alert('In NewSubmissionController.doStore() - Sel material: ' + $scope.selMat + '\nDescr: ' + $scope.subDescription);
var newPI = new SubmissionItem($scope.selMat, $scope.subDescription, '');
$scope.$emit('newPI', newPI);
slidingMenu.setMainPage('pendingList.html', {closeMenu: true});
};
});
// Pending list controller
app.controller('PendingListController', function($scope) {
$scope.pendingItems = [];
$scope.$on('newSubEvent', function(e, subMat, descr) {
alert('In PendingListController, event newSubEvent - sub mat: ' + subMat + '\nDescription: ' + descr);
});
$scope.addPendingItem = function(newPi) {
alert('In PendingListController.addPendingItem() - ' + newPi);
$scope.pendingItems.unshift(newPi);
// Some code here to update the list of pending submissions...
};
});
在此版本中,我曾尝试使用此处其他回复建议的事件系统。不幸的是它不起作用,因为两个控制器不是子控制器和父控制器。将 PendingListController 移动到 NewSubmissionController 中也不起作用,我认为这是因为两个控制器位于两个不同的视图上。
从 NewSubmissionController 调用 PendingListController.addPendingItem() 的最佳解决方案是什么?
如果您想在控制器(不共享 $scope
)之间发送和捕获事件,请使用 $rootScope
及其方法 $on
和 $broadcast
:
myApp.controller("fooCtrl", function($scope, $rootScope){
$scope.foo = "foo";
$scope.broadcast = function() {
$rootScope.$broadcast("fooChange", $scope.foo);
};
});
myApp.controller("barCtrl", function($scope, $rootScope){
$scope.bar = null;
$rootScope.$on("fooChange", function(e, data){
$scope.bar = data;
});
});
捕获 barCtrl
中的事件后,您可以进行 PendingListController.addPendingItem()
调用。
因为您正在使用需要 Multiple Pages Managing Pattern 的多个页面。
因此,从那里,您可以选择为主导航页面添加一个主控制器(在您的情况下,这将是滑动菜单页面),这样您就可以在子控制器之间共享 $rootScope。
建议使用依赖注入作为您的解决方案,您可以使用服务或工厂来帮助"passing/sharing"控制器之间的数据。
下面的演示代码显示:
- 如何利用服务让控制器通信
- 如何使用 $rootScope 实时更新数据
使用服务在控制器之间共享数据
angular.module('app', [])
.service('mainService', function($http) {
var self = this;
self.userList = [];
self.login = function(newUser) {
self.userList.push(newUser + ' ' + (self.userList.length + 1));
return self.userList;
};
})
.controller('MainCtrl', function($rootScope, $scope, mainService) {
$scope.mainAddUser = function() {
$rootScope.users = mainService.login('Main');
};
})
.controller('LoginCtrl', function($rootScope, $scope, mainService) {
$scope.loginAddUser = function() {
$rootScope.users = mainService.login('Login');
};
});
我发现有人问和回答了与我类似的问题,但我认为我的情况有所不同。我从这里的示例代码开始 enter link description here 一个简单的应用程序,它有一个使用 Google 地图的滑动菜单。
我正在创建一个原型,让用户提交新项目,这些新项目被添加到待定项目列表中,然后添加到地图中。我现在专注于第一部分——让用户创建项目,并自动更新待提交列表。然后我添加了一个简单的表单来创建新项目:
<ons-page>
<ons-toolbar fixed-style ng-controller="SlidingMenuController">
<div class="left">
<ons-toolbar-button ng-click="slidingMenu.toggleMenu()"><ons-icon icon="bars"></ons-icon></ons-toolbar-button>
</div>
<div class="center">New Submission</div>
</ons-toolbar>
<ons-row style="margin-top: 10px; text-align: center;">
<ons-col ng-controller="NewSubmissionController">
<p style="font-size: 12px;">Please insert a brief description of your find and its material.</p>
<textarea style="width: 97%;" id="subDescrText" class="textarea" rows="4" placeholder="Type your description here..." value="" ng-model="subDescription"></textarea>
<ons-button style="margin-top: 24px;" ng-click="doStore()">
Store
</ons-button>
</ons-col>
</ons-row>
</ons-page>
另一个页面列出了创建的提交:
<ons-page>
<ons-toolbar>
<div class="left">
<ons-toolbar-button ng-click="slidingMenu.toggleMenu()"><ons-icon icon="bars"></ons-icon></ons-toolbar-button>
</div>
<div class="center">Pending Submissions</div>
</ons-toolbar>
<div style="text-align: center;">
<ons-list id="pendingList" var="aPendingList" ng-controller="PendingListController">
<ons-list-item ng-repeat="pi in pendingItems">
<p>{{pi.description}}</p>
<span>{{pi.material}}</span>
</ons-list-item>
</ons-list>
</div>div>
<p style="margin-top: 12px; text-align: center; width: 100%;" >
<ons-button ng-click="">
Upload All
</ons-button>
</p>
</ons-page>
然后我添加了这些控制器:
app.controller('NewSubmissionController', function($scope) {
$scope.selMat;
$scope.subDescription;
$scope.doStore = function() {
alert('In NewSubmissionController.doStore() - Sel material: ' + $scope.selMat + '\nDescr: ' + $scope.subDescription);
var newPI = new SubmissionItem($scope.selMat, $scope.subDescription, '');
$scope.$emit('newPI', newPI);
slidingMenu.setMainPage('pendingList.html', {closeMenu: true});
};
});
// Pending list controller
app.controller('PendingListController', function($scope) {
$scope.pendingItems = [];
$scope.$on('newSubEvent', function(e, subMat, descr) {
alert('In PendingListController, event newSubEvent - sub mat: ' + subMat + '\nDescription: ' + descr);
});
$scope.addPendingItem = function(newPi) {
alert('In PendingListController.addPendingItem() - ' + newPi);
$scope.pendingItems.unshift(newPi);
// Some code here to update the list of pending submissions...
};
});
在此版本中,我曾尝试使用此处其他回复建议的事件系统。不幸的是它不起作用,因为两个控制器不是子控制器和父控制器。将 PendingListController 移动到 NewSubmissionController 中也不起作用,我认为这是因为两个控制器位于两个不同的视图上。
从 NewSubmissionController 调用 PendingListController.addPendingItem() 的最佳解决方案是什么?
如果您想在控制器(不共享 $scope
)之间发送和捕获事件,请使用 $rootScope
及其方法 $on
和 $broadcast
:
myApp.controller("fooCtrl", function($scope, $rootScope){
$scope.foo = "foo";
$scope.broadcast = function() {
$rootScope.$broadcast("fooChange", $scope.foo);
};
});
myApp.controller("barCtrl", function($scope, $rootScope){
$scope.bar = null;
$rootScope.$on("fooChange", function(e, data){
$scope.bar = data;
});
});
捕获 barCtrl
中的事件后,您可以进行 PendingListController.addPendingItem()
调用。
因为您正在使用需要 Multiple Pages Managing Pattern 的多个页面。
因此,从那里,您可以选择为主导航页面添加一个主控制器(在您的情况下,这将是滑动菜单页面),这样您就可以在子控制器之间共享 $rootScope。
建议使用依赖注入作为您的解决方案,您可以使用服务或工厂来帮助"passing/sharing"控制器之间的数据。
下面的演示代码显示:
- 如何利用服务让控制器通信
- 如何使用 $rootScope 实时更新数据
使用服务在控制器之间共享数据
angular.module('app', [])
.service('mainService', function($http) {
var self = this;
self.userList = [];
self.login = function(newUser) {
self.userList.push(newUser + ' ' + (self.userList.length + 1));
return self.userList;
};
})
.controller('MainCtrl', function($rootScope, $scope, mainService) {
$scope.mainAddUser = function() {
$rootScope.users = mainService.login('Main');
};
})
.controller('LoginCtrl', function($rootScope, $scope, mainService) {
$scope.loginAddUser = function() {
$rootScope.users = mainService.login('Login');
};
});