簡體   English   中英

AngularJS在控制器之間傳遞數據庫數據

[英]AngularJS Pass Database Data between Controllers

我對如何將控制器中加載的數據庫數據傳遞給另一個控制器感到有些困惑。

我從服務器加載了一些列表項,然后單擊每個項,以根據其ID在另一個屏幕上打開該項目的詳細信息。

我讀了一些有關提供服務或使用$ rootScope的問題,但應盡可能避免使用$ rootScope。

就我而言,最好的方法是什么?您能告訴我如何做嗎? 我應該將數據加載到服務中還是以最簡單的方式進行?

使用第一個控制器的列表項:

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

第一控制器

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

}

?>

在您的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調用,也可以從api獲取響應,然后將所需數據暫停到下一個狀態

在兩個控制器之間共享數據不是一個好習慣。

我們需要將數據投入使用,並且可以輕松地與任意數量的控制器共享

服務: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;

一旦服務變量將更新,所有這些控制器變量將自動更新。

首先,強烈建議您在工廠或服務部門進行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服務/工廠-強烈推薦

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

    現在,您可以將此工廠注入到控制器中,並輕松使用setter和getter方法。 不要忘記注入我們之前創建的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); }]); 

現在,要在另一個控制器中獲取數據,您所需要做的就是訪問工廠的getter方法,您就可以獲取數據! 那將是這樣的:

    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路由器通過狀態參數傳遞數據。 在我看來,您正在使用與ionic捆綁在一起的Angular UI路由器。 在路由時也可以使用。 在編寫此答案時,該線程上的另一個答案(由SLearner提供)已經說明了此方法,並且根據您希望的功能級別,或多或少地選擇或不建議。 但是,我認為我不會采用這種解決方案。 您可以在此線程上找到有關此主題的更多答案: AngularJS:使用ui-router將對象傳遞到狀態

因此,在我看來,總結我的答案,最好是去一家有角度的工廠。 恕我直言,這是最好的解決方案。 希望您的詢問得到回答。

干杯!

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM