模型更改后 ngRepeat 不更新
ngRepeat not updating after model changed
我正在尝试编写一些搜索输入代码,以使用 ngResource 从数据库中获取数据。
页面中显示的数据带有 ng-repeat,但是当我进行搜索并且 $scope 已更新时,视图未更新并显示旧数据。
代码如下:
main.html(活动视图)
<div ng-controller="searchCtrl as searchCtrl" layout="column">
<form class="form-inline search-form col-md-offset-1">
<div class="form-group col-md-5">
<label class="sr-only" for="search_location">Location</label> <input
id="search_location" type="search" class="form-control"
ng-Autocomplete ng-model="place" placeholder="Location" />
</div>
<div class="form-group col-md-5">
<label class="sr-only" for="search_tags">Tags</label> <input
style="width: 100%;" id="search_tags" type="search"
class="form-control" id="search_tags" placeholder="Tags">
</div>
<div class="col-md-1">
<md-button class="md-fab md-mini" aria-label="Search" ng-click="searchCtrl.search()"> <md-icon class="md-fab-center"
md-font-icon="glyphicon glyphicon-search" style="color: black;"></md-icon>
</md-button>
</div>
</form>
</div>
<div ng-controller="mainCtrl">
<div ng-repeat="evento in eventi" ng-include="'views/components/event_card.html'" class="col-md-3"></div>
</div>
main.js
'use strict';
app.factory('Eventi', function($resource) {
return $resource('/eventsws/events/:location', {location : '@location'}, {
search: {
method: 'GET',
params: {
'location' : "@location"
},
isArray : true
}
})
});
app.controller('mainCtrl', function($scope, Eventi) {
$scope.eventi = Eventi.query();
});
searchbar.js
'use strict';
app.controller('searchCtrl', function($scope, Eventi) {
$scope.place = null;
this.search = function() {
$scope.eventi = Eventi.search({
'location' : $scope.place
});
}
});
当它启动时,它从数据库中获取所有数据并正确显示它们,当我尝试进行搜索时,$scope.eventi 已更新(我可以在 $[=36 中看到新数据=] 来自调试)但视图仍然显示旧数据并且从不更新。
我试过在搜索函数的末尾使用 $scope.$apply 但结果是一样的。
你知道为什么它不起作用吗?
感谢您的宝贵时间。
只需更改:
$scope.eventi = Eventi.search({
'location' : $scope.place
});
到
Eventi.search({
'location' : $scope.place
}, function(eventi) {
$scope.eventi = eventi
});
这是一个异步调用,因此必须在成功处理程序中分配它。
您 运行 遇到的另一个问题是您的 ng-repeat
不包含在 searchCtrl
范围内的 div 中。更新您的 HTML 以便它像这样被包含:
<div ng-controller="searchCtrl as searchCtrl" layout="column">
<form class="form-inline search-form col-md-offset-1">
... form stuff
</form>
<div ng-repeat="evento in eventi" ng-include="'views/components/event_card.html'" class="col-md-3"></div>
</div>
您在调试中看到的 $scope.eventi 是您的 searchCtrl 中的那个,而不是您的 mainCtrl 中的那个。要更新您的 mainCtrl $scope.eventi,您必须找到其他方法。
一个干净但漫长的解决方案是使用服务在您的控制器中共享变量。
回答评论中的问题:
i can see it updated, but the view still show the old data
我猜想出了什么问题(即使我实际上没有看到您的代码)。
问题
如果你像这样绑定你的 var :
服务
[...]
service.serviceVar = 1;
return service
[...]
这将创建一个带有引用的“1”变量。
控制器
[...]
$scope.myvar = Service.serviceVar;
[...]
这会将 $scope.myvar 绑定到“1”引用。
如果您在您的服务或其他控制器中执行此操作:
service.serviceVar = 2;
您将创建一个带有新引用的新变量“2”,并将此引用分配给 service.serviceVar。糟糕的是,您对旧 1 var 的所有旧引用都不会更新。
解决方案
为避免这种情况,请这样做:
服务
[...]
service.servicevar = {};
service.servicevar.value = 1;
return service
[...]
您使用新引用创建一个对象并将其分配给 servicevar。
您创建一个 var "1" 并将其分配给 servicevar.value.
控制器
[...]
$scope.myvar = Service.servicevar;
[...]
您将 servicevar 引用分配给您的范围变量。
查看
{{myvar.value}}
您可以通过使用变量的 属性 来使用该值。
更新 var 执行此操作:
service.servicevar.value = 2;
您将创建一个带有新引用的新变量“2”,并以此替换旧引用。
但是这次您在控制器中保留对 servicevar 的所有引用。
我希望我说得清楚并且它回答了你的问题。
编辑:
尽量永远不要使用 $scope.$apply。这是一个非常糟糕的做法。如果你用它来做某事,你可能应该找另一个来做(我想这对 Stacks 来说是一个很好的问题:"Why do i need $apply to solve my problem XXXXX")
rsnorman15 关于异步调用的使用有一个很好的观点。也看看他的回答。
这是我的一个 old plunker 使用服务共享属性
我正在尝试编写一些搜索输入代码,以使用 ngResource 从数据库中获取数据。
页面中显示的数据带有 ng-repeat,但是当我进行搜索并且 $scope 已更新时,视图未更新并显示旧数据。
代码如下:
main.html(活动视图)
<div ng-controller="searchCtrl as searchCtrl" layout="column">
<form class="form-inline search-form col-md-offset-1">
<div class="form-group col-md-5">
<label class="sr-only" for="search_location">Location</label> <input
id="search_location" type="search" class="form-control"
ng-Autocomplete ng-model="place" placeholder="Location" />
</div>
<div class="form-group col-md-5">
<label class="sr-only" for="search_tags">Tags</label> <input
style="width: 100%;" id="search_tags" type="search"
class="form-control" id="search_tags" placeholder="Tags">
</div>
<div class="col-md-1">
<md-button class="md-fab md-mini" aria-label="Search" ng-click="searchCtrl.search()"> <md-icon class="md-fab-center"
md-font-icon="glyphicon glyphicon-search" style="color: black;"></md-icon>
</md-button>
</div>
</form>
</div>
<div ng-controller="mainCtrl">
<div ng-repeat="evento in eventi" ng-include="'views/components/event_card.html'" class="col-md-3"></div>
</div>
main.js
'use strict';
app.factory('Eventi', function($resource) {
return $resource('/eventsws/events/:location', {location : '@location'}, {
search: {
method: 'GET',
params: {
'location' : "@location"
},
isArray : true
}
})
});
app.controller('mainCtrl', function($scope, Eventi) {
$scope.eventi = Eventi.query();
});
searchbar.js
'use strict';
app.controller('searchCtrl', function($scope, Eventi) {
$scope.place = null;
this.search = function() {
$scope.eventi = Eventi.search({
'location' : $scope.place
});
}
});
当它启动时,它从数据库中获取所有数据并正确显示它们,当我尝试进行搜索时,$scope.eventi 已更新(我可以在 $[=36 中看到新数据=] 来自调试)但视图仍然显示旧数据并且从不更新。
我试过在搜索函数的末尾使用 $scope.$apply 但结果是一样的。
你知道为什么它不起作用吗?
感谢您的宝贵时间。
只需更改:
$scope.eventi = Eventi.search({
'location' : $scope.place
});
到
Eventi.search({
'location' : $scope.place
}, function(eventi) {
$scope.eventi = eventi
});
这是一个异步调用,因此必须在成功处理程序中分配它。
您 运行 遇到的另一个问题是您的 ng-repeat
不包含在 searchCtrl
范围内的 div 中。更新您的 HTML 以便它像这样被包含:
<div ng-controller="searchCtrl as searchCtrl" layout="column">
<form class="form-inline search-form col-md-offset-1">
... form stuff
</form>
<div ng-repeat="evento in eventi" ng-include="'views/components/event_card.html'" class="col-md-3"></div>
</div>
您在调试中看到的 $scope.eventi 是您的 searchCtrl 中的那个,而不是您的 mainCtrl 中的那个。要更新您的 mainCtrl $scope.eventi,您必须找到其他方法。
一个干净但漫长的解决方案是使用服务在您的控制器中共享变量。
回答评论中的问题:
i can see it updated, but the view still show the old data
我猜想出了什么问题(即使我实际上没有看到您的代码)。
问题
如果你像这样绑定你的 var :
服务
[...]
service.serviceVar = 1;
return service
[...]
这将创建一个带有引用的“1”变量。
控制器
[...]
$scope.myvar = Service.serviceVar;
[...]
这会将 $scope.myvar 绑定到“1”引用。
如果您在您的服务或其他控制器中执行此操作:
service.serviceVar = 2;
您将创建一个带有新引用的新变量“2”,并将此引用分配给 service.serviceVar。糟糕的是,您对旧 1 var 的所有旧引用都不会更新。
解决方案
为避免这种情况,请这样做:
服务
[...]
service.servicevar = {};
service.servicevar.value = 1;
return service
[...]
您使用新引用创建一个对象并将其分配给 servicevar。 您创建一个 var "1" 并将其分配给 servicevar.value.
控制器
[...]
$scope.myvar = Service.servicevar;
[...]
您将 servicevar 引用分配给您的范围变量。
查看
{{myvar.value}}
您可以通过使用变量的 属性 来使用该值。
更新 var 执行此操作:
service.servicevar.value = 2;
您将创建一个带有新引用的新变量“2”,并以此替换旧引用。
但是这次您在控制器中保留对 servicevar 的所有引用。
我希望我说得清楚并且它回答了你的问题。
编辑:
尽量永远不要使用 $scope.$apply。这是一个非常糟糕的做法。如果你用它来做某事,你可能应该找另一个来做(我想这对 Stacks 来说是一个很好的问题:"Why do i need $apply to solve my problem XXXXX")
rsnorman15 关于异步调用的使用有一个很好的观点。也看看他的回答。
这是我的一个 old plunker 使用服务共享属性