在OnsenUI + AngularJS + PhoneGap中的控制器之间传递数据

时间:2016-04-28 12:37:32

标签: javascript angularjs cordova onsen-ui

我发现了类似的问题被问到并回答,但我认为我的情况有所不同。我从这里的示例代码enter link description here开始,为一个带有使用谷歌地图的滑动菜单的简单应用程序。

我正在创建一个原型,允许用户提交添加到待处理项列表中的新项目,然后添加到地图中。我现在专注于第一部分 - 让用户创建项目,并自动更新待处理提交列表。然后我添加了一个简单的表单来创建新项目:

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

在这个版本中,我曾尝试使用此处其他回复建议的事件系统。不幸的是它不起作用,因为两个控制器不是孩子和父母。在 NewSubmissionController 中移动 PendingListController 也不起作用,我认为这是因为两个控制器在两个不同的视图上。

从NewSubmissionController调用PendingListController.addPendingItem()的最佳解决方案是什么?

2 个答案:

答案 0 :(得分:2)

当您使用需要Multiple Pages Managing Pattern的多个页面时。

因此,您可以选择为主导航页面添加主控制器(在您的情况下,即滑动菜单页面),这样您就可以在子控制器之间共享$ rootScope。

建议使用依赖注入作为您的解决方案,您可以使用服务或工厂来帮助&#34;传递/共享&#34;控制器之间的数据。

下面的演示代码显示:

  • 如何利用服务让控制器进行通信
  • $ 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');
  };
});

演示http://plnkr.co/edit/OvG0oj6EmDU5GMi1eBaU?p=preview

答案 1 :(得分:1)

如果您想在控制器之间发送和捕获事件(不要共享$scope),请使用$rootScope及其方法$on$broadcast:< / p>

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()来电。

DEMO http://jsbin.com/kolorixoti/1/edit?html,js,output