Почему ng-repeat не обновляется динамически?

Я буквально проверил каждый ng-repeat вопрос там, но многие из них не имеют дело с базами данных, и люди просто используют массивы в JS и простой $scope.array.push("stuff") работает на них.

я пробовал $scope.apply, $rootScope и даже вызов запроса GET сразу после успешного запроса POST.

У меня есть форма с 2 текстовыми вводами, date а также content,
Когда кнопка отправки нажата, дата и контент добавляются в базу данных MySQL с использованием PHP.

Данные просто добавляются в базу данных MySQL, и извлечение также работает правильно.
Даже запрос GET внутри успешного запроса POST выполняется.
Поэтому я не понимаю, почему это заставляет меня обновить страницу, чтобы увидеть обновленную ng-repeat Результаты.

Я что-то пропустил?
Любая помощь или предложения с благодарностью, спасибо!

Изображение


Соответствующий HTML код

<div ng-controller="insertController">
<h2> What I learned today </h2>
<form>
Date <br>
<input type="text" ng-model="date"><br><br>
Content <br>
<textarea rows="10" cols="50" ng-model="content"></textarea><br><br>
<input type="button" value="Submit" ng-click="insertdata()">
</form>
</div>

<div ng-controller="fetchController">
<span ng-repeat="item in results">
{{item.date}}<br>
{{item.content}}<br><br>
</span>
</div>

insertController.js

var app = angular.module('myApp', []);

app.controller('insertController', function($scope, $http) {
$scope.insertdata = function() {
$http({
method: 'POST',
url: 'http://localhost/storestuff/insert.php',
data: {'date':$scope.date, 'content':$scope.content, 'in':'json-format'},
headers: {'Content-Type': 'application/x-www-form-urlencoded'}
})
.then(function(res) {
console.log("Successful response", res)
$scope.date = "";
$scope.content = "";
$http.get('http://localhost/storestuff/fetch.php')
.then(function successCallback(response) {
alert("GOT NEW DATA");
$scope.results = response.data; // Allow angular to access the PHP output data
});
$scope.apply;
})
.catch(function(err) {
console.error("Error with POST", err);
});
}
});

insert.php

<?php

header('Access-Control-Allow-Origin: *');

$theConnection = mysqli_connect("localhost", "root", "", "storestuff");
if(mysqli_connect_errno()) {
echo "Failed to connect to MySQL.";
}

$theData = json_decode(file_get_contents('php://input'));
$date = mysqli_real_escape_string($theConnection, $theData->date);
$content = mysqli_real_escape_string($theConnection, $theData->content);

mysqli_query($theConnection, "INSERT INTO thestuff(date, content) VALUES('$date', '$content')");

mysqli_close($theConnection);

?>

fetchController.js

app.controller('fetchController', function ($scope, $http) {
$http.get('http://localhost/storestuff/fetch.php')
.then(function successCallback(response) {
$scope.results = response.data; // Allow angular to access the PHP output data
});
});

fetch.php

<?php
header('Access-Control-Allow-Origin: *'); // clientside(Node) <-> serverside(PHP)

$mysqli = new mysqli("localhost", "root", "", "storestuff");

if($mysqli->connect_error) {
printf("Connect failed: %s\n", $mysqli->connect_error);
exit();
}

$query = "SELECT * FROM thestuff";
$theData = array();

if($result = $mysqli->query($query)) {
while($row = mysqli_fetch_array($result)) {
$theData[] = array(
'date'=>$row['date'],
'content'=>$row['content']);
}
echo json_encode($theData); // Echo the output for the controller to access
$result->free(); // Free the result set
}
else {
echo "0 results.";
}
$mysqli->close(); // Close the connection
?>

1

Решение

Проблема с этим кодом в том, что у вас есть два разных контроллера, оба с разными областями действия. Вставка / обновление объекта / массива $ scope.results в одном контроллере не приведет к обновлению другого $ scope; это отдельные отдельные области, обе с копией данных.

Использование двух контроллеров выглядит правильно в вашем случае. Однако вы должны использовать сервис для доступа к вашим удаленным данным. Проверьте этот ответ для некоторых советов по этому https://stackoverflow.com/a/20181543/2603735.

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

2

Другие решения

Для тех, кто когда-либо натыкается на мой вопрос, я не хочу просто оставлять там свой неработающий код без ответа, но я также не могу отредактировать вопрос и указать в ответе причину, которая бы не соответствовала цели StackOverflow.

Так вот мой ответ на мой собственный вопрос.

Мне пришлось внести немало изменений в то, что у меня было раньше. Самое большое изменение на сегодняшний день, это то, как я обработал данные, которые были возвращены fetch.php,

Вместо того, чтобы просто взять вывод в $scope.results = response.data;, который бы работал нормально, если бы я не добавлял динамически в базу данных, но в этом случае я использовал сервис.
(Спасибо @ jayden-meyer за предложение услуг Angular.)

Служба позволила мне получить доступ к тому же массиву из моего insertController и из моего fetchController вместо того, чтобы иметь копию одного и того же массива в обоих контроллерах, что было моей проблемой.


Никаких изменений в HTML код.
Без изменений insert.php,
Без изменений fetch.php,


insertController.js
Я удалил посторонний запрос GET, который у меня был внутри .then метод, который был совершенно ненужным, так как я могу просто нажать на существующий массив.
(Спасибо @charlietfl за подсказку)
Вместо этого я добавил resultsService.addItem($scope.date, $scope.content); внутри .then метод.
Я также добавил свой сервис в качестве аргумента.
app.controller('insertController', function($scope, $http, resultsService) {


result.js

app.service('resultsService', function() {
var results = new Array();

var addItem = function(date, content) {
var obj = new Object();
obj["date"] = date;
obj["content"] = content;
results.push(obj);
}

var getItems = function() {
return results;
}

return {
addItem: addItem,
getItems: getItems
};

});

fetchController.js

var size = 0;
var count = 0;

app.controller('fetchController', function ($scope, $http, resultsService) {
$http.get('http://localhost/storestuff/fetch.php')
.then(function successCallback(response) {
size = (response.data).length;
while(count < size) {
var date = response.data[count].date;
var content = response.data[count].content;
resultsService.addItem(date, content);
count++;
}
size = 0;
count = 0;
$scope.results = resultsService.getItems();
});
});
0