2016-04-28 1 views
1

Я нашел похожие вопросы к моему вопросу и ответил, но я думаю, что мой сценарий отличается. Я начал с примера кода enter link description here для простого приложения с раздвижным меню, которое использует Карты Google.Передача данных между контроллерами в OnsenUI + AngularJS + PhoneGap

Я создаю прототип, который позволяет пользователям отправлять новые элементы, которые добавляются в список ожидающих элементов, а затем добавляется на карту. Сейчас я сосредоточен на первой части - позволяя пользователям создавать элементы и автоматически обновлять список ожидающих представлений. Затем я добавил простую форму, чтобы создать новый предмет:

<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 тоже не работает, и я считаю, это потому, что два контроллера находятся на двух разных видах.

Что является лучшим решением для вызова PendingListController.addPendingItem() из NewSubmissionController?

ответ

2

Как вы используете несколько страниц, которые требуют Multiple Pages Managing Pattern.

Итак, у вас есть выбор, чтобы добавить основной контроллер для главной страницы навигации (в вашем случае это будет скользящая страница меню), поэтому вы можете совместно использовать $ rootScope среди дочерних контроллеров.

В качестве решения целесообразно использовать Injection Dependency, вы можете использовать сервис или завод, чтобы помочь «передавать/делиться» вашими данными между контроллерами.

код демо ниже показывает:

  • как вы можете использовать службы, чтобы контроллеры общаться
  • как $ 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

+0

Просто так, что я его получаю - поскольку в моем случае у меня есть скользящий контроллер меню на главной странице навигации, я должен определить мои _NewSubmissionController_ и _PendingListController_ как свои дочерние контроллеры, чтобы они могли использовать область контроллера скользящего меню как root объем? – Btz

+0

Я изменил свой код, следуя вашему примеру, и он сработал. Я благодарен, но я хотел бы лучше понять. Почему это работает? Контроллеры не определены как дети чего-либо еще, так что же такое rootScope? И, кстати, есть ли хороший учебник/документация, которая затрагивает эти темы? Я мог бы проследить и понять основную информацию на веб-сайте Angular, но она останавливается раньше, чем эти темы. – Btz

+1

Определяется, где вы размещаете свои контроллеры в шаблоне html. Короче говоря, область наследуется от родительского к дочернему виду: (rootScope -> parent scope -> child scope), так что ребенок все равно может получить доступ к области своих родителей. Для более подробных объяснений я нашел [Угловое наследование области] (https://github.com/angular/angular.js/wiki/Understanding-Scopes#angular-scope-inheritance), где есть хороший пример и диаграммы, которые вы можете следовать. Надеюсь, поможет. –

1

Если вы хотите, чтобы отправлять и фиксировать события между контроллерами (которые не разделяют $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() call.

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

+0

Пример в демонстрационной версии, но когда я интегрирую его в свой существующий код, происходит нечто странное. В первый раз я вызываю _PendingListController.addPendingItem() _ Я не получаю предупреждения. Второй раз я их получаю. В третий раз два набора предупреждений. И так далее. – Btz