Почему это ng-show ng-hide не работает
У меня есть простое приложение в AngularJS. Я хочу показывать сообщения динамически, когда делается запрос AJAX. К сожалению, это всегда в скрытом состоянии, и я не могу понять, почему.
HTML:
<div ng-show="message">
<h2>show</h2>
</div>
<div ng-hide="!message">
<h2>Hide</h2>
</div>
Контроллер AngularJS:
function merchantListController($scope, $http, $rootScope, $location, global) {
$http({
method: 'POST',
url: global.base_url + '/merchant/list',
}).success(function($data) {
if ($data.status === 'success') {
$scope.merchants = $data.data;
$scope.$apply(function(){
$scope.message = true;
});
}
});
}
Ответы
Ответ 1
Вероятная причина, по которой она не работает, заключается в том, что вы создаете новое свойство scope в пределах дочерней области, вместо того, чтобы переписывать свойство message
в области merchantListController, как вы ожидали.
// The following assignment will create a 'message' variable
// in the child scope which is a copy of the scope variable
// in parent scope - effectively breaking two-way model binding.
$scope.message = true;
Чтобы устранить это, убедитесь, что вы привязываете ссылку на свойство на вашей модели, а не на свойство в области.
HTML
<div ng-show="my.message">
<h2>show</h2>
</div>
<div ng-hide="!my.message">
<h2>Hide</h2>
</div>
контроллер
function merchantListController($scope, $http, $rootScope, $location, global) {
// Initialize my model - this is important!
$scope.my = { message: false };
$http({
method: 'POST',
url: global.base_url + '/merchant/list',
}).success(function($data) {
if ($data.status === 'success') {
$scope.merchants = $data.data;
// modify the 'message' property on the model
$scope.my.message = true;
}
});
});
объяснение
Причина этого в том, что модель my
решается с использованием правил наследования областей. То есть, если my
не существует в текущей области, тогда выполните поиск в my
родительской области, пока она не будет найдена, или поиск остановится в $ rootScope. После того, как модель найдена, свойство message
перезаписывается.
Ответ 2
Логика show/hide ошибочна... измените ее так: ng-hide = "message"
<div ng-show="message">
<h2>show</h2>
</div>
<div ng-hide="message">
<h2>Hide</h2>
</div>
ng-hide нуждается в переменной, когда нужно скрыть, ng-show нуждается в ней, когда отображается, поэтому условие ng-show = "message" & ng-hide = "! message" одинаково.
Попробуйте сделать это:
<div ng-show="message">
<h2>show</h2>
</div>
<div ng-show="!message">
<h2>Hide</h2>
</div>
Просто для тестирования... измените свой класс http на это:
$http({
method: 'POST',
url: global.base_url + '/merchant/list',
}).success(function($data) {
$scope.message = true;
}).error(function($data) {
$scope.message = false;
});
Ответ 3
Because you did a mistake...
ng-show="message" and ng-hide="!message" both points to the same value..
Correct it as..
<div **ng-show="message"**>
<h2>show</h2>
</div>
<div **ng-hide="message"**>
<h2>Hide</h2>
</div>
//or you can do in your way as...
<div **ng-show="message"**>
<h2>show</h2>
</div>
<div **ng-show="!message"**>
<h2>Hide</h2>
</div
Ответ 4
Итак, проведя время по 2-летнему вопросу, я положу что-то здесь.
$scope.apply()
является необходимым и, вероятно, вызовет ошибку, заявив, что применение уже выполняется. Если вы делаете это правильно, вы должны очень редко или никогда не называть эту функцию. Основное использование было бы, если вы используете сторонние библиотеки, которые угловые не могли следить за изменениями или видеть, что они делают, и вам нужно запустить цикл дайджеста вручную.
Я бы посоветовал инициализировать переменные, поэтому ваш контроллер будет выглядеть так (я также извлек http-запрос в службу и then
использовал для обработки ответов и ошибок, поскольку .success()
устарели):
function merchantService($http) {
function post() {
return $http.get('localhost');
//Just a dummy $http request, instead of yours.
//return $http.post(global.base_url + '/merchant/list');
}
/* this is rather implicit, but if you are doing a service like this,
you can keep the functions "private" and export an object, that
contains the functions you wish to make "public" */
return {
post: post
};
}
function merchantListController($scope, merchantService) {
/* Initialize the variable, so ng-show and ng-hide
have something to work with in the beginning
rather then just being undefined. */
$scope.message = false;
// call the post from the function
merchantService.post()
.then(function (response) {
/* The first then() will hold the response
if the request was OK */
console.log(response);
$scope.merchants = response.data;
/* Since this then() will be triggered on a successful request
we are safe to say $scope.message should now be true. */
$scope.message = true;
})
.then(function (error) {
// The second one is for the failed request.
console.error(error);
});
}
var app = angular.module('myApp', []);
app.controller('merchantListController', merchantListController);
app.factory('merchantService', merchantService);
Здесь вы можете найти рабочую скрипку: https://jsfiddle.net/vnjbzf3o/4/
Ответ 5
Прежде всего, вызов $ scope. $ Apply() не нужен.
Если show
div никогда не отображается, это означает, что $scope.message = true;
не выполняется. Если это не выполнено, это означает, что либо ваш запрос AJAX не выполняется, либо что $data.status === 'success'
никогда не будет истинным.
Отлаживайте свой код или добавляйте трассировки console.log() для проверки значений ваших переменных и посмотрите, что выполнено, а что нет. Стандартная отладочная работа.
Кроме того, не префикс вашей переменной данных с помощью $. Обычно $ зарезервирован для услуг с угловым сервисом.
Ответ 6
Тебе это не нужно. Просто введите $ scope. $ Parent. $ Message = true. Поскольку предыдущий комментарий говорит об этом, потому что вы находитесь в области Child, а исходная привязка - с переменными родительской области. Однако я считаю, что его глупый язык не имеет общей памяти как для родительских, так и для дочерних переменных. Он работал для меня и не требовал упоминания ng-контроллера. Такой сумасшедший язык, я потратил день на это. Однако спасибо за все ценные отзывы.