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

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

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

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

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

}

?>
0
madsongr 5 Сен 2016 в 22:41

3 ответа

Лучший ответ

В вашем 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 для имитации перенаправления страницы master-details

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

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

1
SLearner 6 Сен 2016 в 14:37

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

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

Сервис: 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;

Как только служебная переменная обновит, все эти переменные контроллера автоматически обновятся.

0
Ali Adravi 6 Сен 2016 в 13:51

Прежде всего, настоятельно рекомендуется совершать 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. Используйте Angular service / factory - НАСТОЯТЕЛЬНО РЕКОМЕНДУЕТСЯ

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

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

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

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

Ура!

0
Community 23 Май 2017 в 10:29