代码之家  ›  专栏  ›  技术社区  ›  Btz

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

  •  1
  • Btz  · 技术社区  · 9 年前

    我发现有人问我类似的问题,也有人回答,但我认为我的情况不同。我从这里的示例代码开始 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...
        };
    });
    

    在这个版本中,我尝试使用其他回复建议的事件系统。不幸的是,它不能工作,因为两个控制器不是子控制器和父控制器。移动 挂起列表控制器 在…内 新建提交控制器 也不起作用,我想这是因为两个控制器在两个不同的视图上。

    调用PendingListController的最佳解决方案是什么。从NewSubmissionController添加PendingItem()?

    2 回复  |  直到 9 年前
        1
  •  2
  •   Trtshen Chaw    9 年前

    由于您正在使用多个需要 Multiple Pages Managing Pattern .

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

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

    下面的演示代码显示:

    • 如何利用服务让管制员 交流
    • $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

        2
  •  1
  •   Ozrix    9 年前

    如果要在控制器(不共享)之间发送和捕获事件 $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() 呼叫

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