我在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;
});
}
});
}
答案 0 :(得分:22)
它不起作用的可能原因是您在子范围内创建 新 范围属性,而不是覆盖merchantListController中的message
属性范围如你所料。
// 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
属性。
答案 1 :(得分:8)
显示/隐藏逻辑错误...更改为: ng-hide =&#34;消息&#34;
<div ng-show="message">
<h2>show</h2>
</div>
<div ng-hide="message">
<h2>Hide</h2>
</div>
ng-hide需要变量何时隐藏,ng-show需要何时显示,因此条件 ng-show =&#34; message&#34; &安培; ng-hide =&#34;!message&#34; 是一样的。
尝试这样做:
<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;
});
答案 2 :(得分:1)
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
答案 3 :(得分:1)
所以,在花了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/
答案 4 :(得分:1)
$ scope。$ digest()函数遍历$ scope对象及其子$ scope对象(如果有)中的所有手表。当$ digest()遍历手表时,它将为每个手表调用value函数。如果value函数返回的值与上次调用它返回的值不同,则会调用该手表的侦听器函数。
只要AngularJS认为有必要,就会调用$ digest()函数。例如,在执行按钮单击处理程序之后,或者在AJAX调用返回之后(在执行done()/ fail()回调函数之后)。
您可能会遇到一些极端情况,其中AngularJS不会为您调用$ digest()函数。通常,您会通过注意数据绑定不会更新显示的值来检测到这一点。在这种情况下,调用$ scope。$ digest()它将起作用。或者,您也许可以使用$ scope。$ apply()
您可以这样做:
HTML
<div ng-hide="message"> <h2>show</h2> <div>
<div ng-hide="!message"> <h2>Hide</h2> </div>
JS
$scope.message = true;
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 = false;
$scope.$digest();
});
}
});
答案 5 :(得分:0)
首先,调用$ scope。$ apply()是不必要的。
如果从未显示show
div,则表示未执行$scope.message = true;
。如果它没有被执行,那意味着您的AJAX请求不成功,或者$data.status === 'success'
永远不会成立。
调试代码,或添加console.log()跟踪以检查变量的值,并查看执行的内容和不执行的内容。标准调试工作。
另外,不要在数据变量前加上$。 $通常保留给角度提供的服务。
答案 6 :(得分:-2)
你并不需要这一切。只做$ scope。$ parent。$ message = true。正如前面的评论所说,因为你在Child范围内,而原始绑定是与父范围变量一起使用的。但是我相信它的愚蠢语言没有父变量和子变量的共同记忆。它对我有用,并且不需要提及ng-controller。这么疯狂的语言,我为此浪费了一天。不过感谢所有有价值的反馈。