AngularJS передает данные базы данных между контроллерами

0

Я немного смущен тем, как передавать данные моей базы данных, загруженные в контроллер, на другой контроллер.

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

Я прочитал некоторые вопросы о предоставлении услуги или использовании $ rootScope, но следует избегать как можно большего количества $ rootScope.

Каков наилучший способ сделать это в моем случае, и не могли бы вы показать мне, как это сделать? Должен ли я загружать данные внутри службы или есть самый простой способ в моем случае?

элемент списка с использованием 1-го контроллера:

<div class="item item-body list-container" id="temporada2016-list-item-container4" ng-model="item_id" ng-repeat="x in items" item="x" href="#/x/{{x.ID}}" ng-click="open_item(x)" ng-show="news_list">

        <div id="temporada2016-markdown7" style="margin-top:0px;color:#666666;">
            <h2 style="color:#008BBB;">{{ x.TITLE }}</h2>
        </div>

</div>

1-й контроллер

.controller('temporada2016Ctrl', ['$scope', '$http', function ($scope, $http) {

$scope.active_news_btn = true;
$scope.search_news = true;
$scope.news_list = true;
$scope.albums_list = false;

$http.get("http://localhost/select-news.php").then(function(response){

    console.log(response);
    console.log(JSON.stringify(response));

    $scope.items = response.data;

});

$scope.open_item = function(x){

    //alert("Item id: " + x.ID);
    $http.post("http://localhost/select-news-by-id.php", {'item_id': x.ID}).then(function(response){

    console.log(response);
    console.log(JSON.stringify(response));

    $scope.all = response;
    $scope.title = response.data[0].TITLE;
    $scope.body = response.data[0].BODY;


 });


 }
}])

второй экран (подробности) с использованием второго контроллера, где я хочу загрузить один и тот же заголовок и новостной блок

<ion-view title="Detalhes" id="page4" style="background-color:#FFFFFF;">
  <ion-content padding="true" class="has-header">
    <h3 id="detalhes-heading1" style="color:#008BBB;font-weight:600;font-style:italic;">{{title}}</h3>
    <div id="detalhes-markdown3" style="color:#000000;">
        <p>{{body}}</p>
    </div>
    <form id="detalhes-form4" class="list">
        <button id="detalhes-button6" style="color:#008BBB;text-align:left;border-radius:9px 9px 9px 9px;" class="button button-calm  button-clear icon ion-ios-heart-outline like_btn"></button>
        <label class="item item-input" id="detalhes-textarea1">
            <span class="input-label"></span><textarea placeholder=""></textarea>
        </label>
    </form>
    <button id="detalhes-button17" style="color:#FFFFFF;" class="button button-positive">Comment</button>
  </ion-content>
</ion-view>

Второй контроллер

.controller('detalhesCtrl', ['$scope', '$stateParams', function ($scope, $stateParams) {


}])

PHP

<?php 

include_once('conn.php');

$data = json_decode(file_get_contents("php://input"));

if(property_exists($data, 'item_id')){

$item_id = $data->item_id;
$sql = $mysqli->query("SELECT * FROM news WHERE id = '".$item_id."'");

if($sql->num_rows > 0){
        while($row = $sql->fetch_array(MYSQLI_BOTH)){
            $registro = array(
                "ID" => $row['id'],
                "TITLE" => $row['title'],
                "BODY" => $row['body']
                );

        $retorno[] = $registro;

        }   
}

    $mysqli->close();
    $retorno = json_encode($retorno);
    echo $retorno;

}

?>
Теги:
ionic-framework

3 ответа

1
Лучший ответ

В вашем app-config

$stateProvider
      .state('master', {
        url: '/master',
        templateUrl: 'views/master.html',
        controller: 'MasterCtrl',
        data: {
          someThingToPassToMasterState: false
        }
      })
      .state('details', {
        url: '/details',
        data : {
          somethingToPassToDetailsState: false
        },
        templateUrl: 'views/details.html',
        controller: 'DetailsCtrl'
      });

И затем в вашем MasterCtrl

$scope.onClick = function(obj) {
  var dataToPass = {};
  dataToPass.obj = obj;
  dataToPass.somethingElse = 'blah blah';
  $state.go('details', {somethingToPassToDetailsState: dataToPass});
}

// Now in the DetailsCtrl
if(!$state.params.somethingToPassToDetailsState) {
  // handle this  
  // maybe do a $state.go('default') and then return to end execution of this controller
}

// Some code

В master.html, используя ng-repeat для имитации перенаправления страницы мастер-данных

<div ng-repeat="o in objects">
  <div ng-click="redirectTo(o)">{{o.name}}</div>
</div>

Идея состоит в том, чтобы передать день непосредственно из одного состояния в другое при переходе государства. Вы можете либо заплатить мне, либо сделать api call ПОСЛЕ перехода к новому состоянию или получить ответ от api, а затем передать данные в следующее состояние

  • 0
    что вы говорите, чтобы отправить идентификатор из элемента списка в DetailsCtrl для выполнения метода $ http.post и загрузки данных внутри этого контроллера?
  • 0
    Вы можете сделать вызов API после перенаправления, или вы можете сделать вызов API, а затем в ответ сделать $ state.go (). Каким бы способом вы не захотели это сделать
Показать ещё 7 комментариев
0

Прежде всего, настоятельно рекомендуется делать свои http-звонки на заводе или в службе. Это сделает ваш код более многоразовым, и он будет выглядеть примерно так:

app.factory("responseFactory", function($http) {
  return {
      getData: function() {
          //Code for making http call goes in here
          $http.get("http://localhost/select-news.php").then(function(response){
            return(response.data);
          });
      },
      postData: function(x) {
          $http.post("http://localhost/select-news-by-id.php", {'item_id': x.ID})
          .then(function(response){
            return(response.data);
          });
      }
  };
});

Позднее вы можете использовать это для вызова своего контроллера, введя эту фабрику в свой контроллер и называя эту фабрику примерно так:

app.controller('temporada2016Ctrl', ['$scope', 'responseFactory', function ($scope, responseFactory) {
    $scope.items = responseFactory.getData();
    $scope.opnItem = function(x){
        $scope.all = responseFactory.postData(x);
        $scope.title = all.TITLE;
        $scope.body = all.BODY;
    }
}]);

Теперь, чтобы сделать данные доступными на вашем втором контроллере, вы можете сделать несколько вещей.

  1. Пропустите его через $ rootScope, который, как вы уже сказали, следует избегать как можно больше, чтобы не загромождать rootScope. Это может иметь много последствий. - НЕ РЕКОМЕНДУЕТСЯ

  2. Сделайте вызов службы от второго контроллера, и у вас будут все необходимые данные из api. Однако, если вы отредактируете данные в первом контроллере и хотите сделать отредактированные данные доступными во втором контроллере, это будет невозможно с помощью этого метода. Кроме того, создание HTTP-звонков является дорогостоящим, и настоятельно рекомендуется свести к минимуму количество HTTP-вызовов в приложении. - НЕ РЕКОМЕНДУЕТСЯ

  3. Использование Угловое обслуживание/завод - ВЫСОКО РЕКОМЕНДУЕТСЯ

    app.factory('commonData', function() {
        var data;
    
        return{
            setData: setData,
            getData: getData
        };
    
        //setter
        function setData(dataToBeShared) {
            data = dataToBeShared;
        }
    
        //getter
        function getData() {
            return data;
        }
    
    });
    

    Теперь вы можете ввести эту фабрику в свои контроллеры и легко использовать методы настройки и получения. Не забудьте ввести responseFactory, который мы создали ранее! После ввода его в свой первый контроллер вы можете вызвать фабрику commonData и использовать метод setter для установки данных, примерно так:

    app.controller('temporada2016Ctrl', ['$scope', 'responseFactory', 'commonData', function ($scope, responseFactory, commonData) {
    
        //All your controller code, including calling the factory like I earlier explained...it all goes here
    
        commonData.setData(passTheDataThatYouWantToShare);
    
    }]);
    

Теперь, чтобы получить данные в другом контроллере, все, что вам нужно сделать, это получить доступ к заводскому методу получения, и вы получите данные! Это будет примерно так:

    app.controller('detalhesCtrl', ['$scope', '$stateParams', 'commonData', function ($scope, $stateParams, commonData) {
        $scope.commonData = commonData.getData();
        //Use $scope.commonData to use all the data that has come in from first controller
    }]);

Теперь данные, которые передаются от контроллера 1, хранятся на заводе и могут быть получены во втором контроллере, когда захотите. Предположим, вы хотели бы отображать их как панели, рядом друг с другом, вы можете добавить наблюдателей, иначе этот метод должен сработать для вас.

ПРИМЕЧАНИЕ. Это может быть достигнуто без использования методов setter и getter, но использование их является хорошей практикой и очень полезно, когда приложение становится больше.

  1. Передача данных через параметры состояния с использованием углового маршрутизатора пользовательского интерфейса. Мне кажется, что вы используете Angular UI router, который поставляется в комплекте с ионным. Это также можно использовать при маршрутизации. Во время написания этого ответа еще один ответ на этот вопрос (от SLearner) уже объяснил этот метод, и если он рекомендуется или нет, это более или менее ваш выбор в зависимости от уровня требуемой функциональности. Однако, на мой взгляд, я бы не стал заниматься этим решением. Вы можете найти еще несколько ответов на эту тему в этой теме: AngularJS: передать объект в состояние с помощью ui-router

Итак, завершая свой ответ, на мой взгляд, лучше всего пойти на угловую фабрику. ИМХО, это лучшее решение. Надеюсь, на ваши вопросы ответят.

Ура!

  • 0
    getData () загружает данные, когда я использую console.log (JSON.stringify (response)); но ничего не отображается в списке после использования $ scope.items = responseFactory.getData (); в контроллере
  • 0
    Возможно, вы захотите проверить, хранятся ли значения в $ scope.items. Сохраняйте точки останова, отлаживайте приложение и проверяйте, загружаются ли данные в область. Регистрация области также может быть полезна. Рекомендуется использовать службу $ log, предоставляемую angular вместо console.log. Вы также можете попробовать напрямую зарегистрировать responseFactory.getData () и проверить, возвращает ли фабрика данные.
Показать ещё 4 комментария
0

Обмен данными между двумя контроллерами не является хорошей практикой.

Нам нужно поместить данные в сервис, которые могут быть легко доступны для любого количества контроллеров

Сервис: MyService

this.dbDataSearch = function(parameters){
  // Search record from database
  this.resultData = data;
}

В Convtoller 1:

 $scope.data = MyService.resultData;

В Convtoller 2:

 $scope.data = MyService.resultData;

....

В Convtoller n:

 $scope.data = MyService.resultData;

После изменения сервисной переменной все эти переменные контроллера автоматически обновляются.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню