[英]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;
}
}]);
現在,要使數據在第二個控制器中可用,您可以做一些事情。
通過$ rootScope傳遞它,正如您已經說過的那樣,應盡可能避免使用它,以免使rootScope混亂。 它可能會帶來許多后果。 - 不建議
從第二個控制器進行服務調用,您將從api獲得所需的所有數據。 但是,如果您在第一個控制器中編輯數據並希望在第二個控制器中提供已編輯的數據,則使用此方法將無法實現。 另外,進行HTTP調用的成本很高,強烈建議您盡量減少應用中的HTTP調用次數。 - 不建議
使用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方法來實現,但是使用它們是一種很好的做法,當應用程序變大時,它非常有用。
因此,在我看來,總結我的答案,最好是去一家有角度的工廠。 恕我直言,這是最好的解決方案。 希望您的詢問得到回答。
干杯!
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.