我想编写一些搜索输入来使用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被更新(我可以从调试中查看$ scope.eventi中的新数据)但视图仍然显示旧数据,从不更新。
我尝试使用$ scope。$在搜索功能结束时应用但结果是相同的。
你知道它为什么不工作吗?
感谢您的时间。
答案 0 :(得分:6)
您在调试中看到的$ scope.eventi是searchCtrl中的那个,而不是mainCtrl中的那个。要更新mainCtrl $ scope.eventi,你必须找到另一种方法。
干净但很长的解决方案是使用服务来共享控制器中的变量。
回答评论中的问题:
我可以看到它已更新,但视图仍显示旧数据
我想问题是什么(即使我实际上没有看到你的代码)。
如果你像这样绑定var:
<强>服务强>
[...]
service.serviceVar = 1;
return service
[...]
这将创建一个&#34; 1&#34;带引用的var。
控制器
[...]
$scope.myvar = Service.serviceVar;
[...]
这会将$ scope.myvar绑定到&#34; 1&#34;参考
如果您在服务中或在其他控制器中执行此操作:
service.serviceVar = 2;
您将创建一个新的var&#34; 2&#34;使用新引用,您将此引用分配给service.serviceVar。对旧的1 var的所有旧引用都不会更新。
为避免这样做:
<强>服务强>
[...]
service.servicevar = {};
service.servicevar.value = 1;
return service
[...]
使用新引用创建对象并将其分配给servicevar。 你创建了一个var&#34; 1&#34;并将其分配给servicevar.value。
控制器
[...]
$scope.myvar = Service.servicevar;
[...]
将servicevar引用分配给范围var。
查看强>
{{myvar.value}}
您可以使用var。
的属性来使用该值更新var执行此操作:
service.servicevar.value = 2;
您将创建一个新的var&#34; 2&#34;使用新引用并替换此引用的旧引用。
但是这次你在控制器中保存了对servicevar的所有引用。
我希望我很清楚,它会回答你的问题。
编辑:
尽量永远不要使用$ scope。$ apply。这是一个非常糟糕的做法。如果你使用它来制作一些东西,你应该找到另一个可以做到这一点(对于Stacks我将会是一个很好的问题:&#34;为什么我需要$申请来解决我的问题XXXXX&#34;)
rsnorman15对您使用异步调用有一个很好的观点。看看他的答案。
以下是我使用服务共享属性的old plunker之一
答案 1 :(得分:2)
只需改变:
$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>