Я немного смущен тем, как передавать данные моей базы данных, загруженные в контроллер, на другой контроллер.
Я загружаю некоторые элементы списка с сервера, и на каждом элементе щелкните Я хочу открыть сведения об этом элементе на другом экране в соответствии с его идентификатором.
Я прочитал некоторые вопросы о предоставлении услуги или использовании $ 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;
}
?>
В вашем 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, а затем передать данные в следующее состояние
Прежде всего, настоятельно рекомендуется делать свои 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-вызовов в приложении. - НЕ РЕКОМЕНДУЕТСЯ
Использование Угловое обслуживание/завод - ВЫСОКО РЕКОМЕНДУЕТСЯ
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, но использование их является хорошей практикой и очень полезно, когда приложение становится больше.
Итак, завершая свой ответ, на мой взгляд, лучше всего пойти на угловую фабрику. ИМХО, это лучшее решение. Надеюсь, на ваши вопросы ответят.
Ура!
Обмен данными между двумя контроллерами не является хорошей практикой.
Нам нужно поместить данные в сервис, которые могут быть легко доступны для любого количества контроллеров
Сервис: 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;
После изменения сервисной переменной все эти переменные контроллера автоматически обновляются.