我正在尝试使用服务调用来更新结果数组,然后在ng-repeat中使用它。在表单提交上,我调用必要的服务,并通过promise对象上的.then()连接我的回调。不幸的是,一旦我开始从文本输入中删除字符,视图才会更新。然后显示正确的结果。
以下是我的观点:
<div id="main" ng-controller="SearchController as searchCtrl">
<div class="header" >
<h1>Search and Add Tracks</h1>
</div>
<!--Search Bar-->
<form class="pure-form pure-g" novalidate ng-submit="searchCtrl.search()">
<div class="pure-u-1">
<input class="pure-input-1" type="search" placeholder="Search for tracks" ng-model="searchCtrl.query">
</div>
</form>
<!--Search Results Table-->
<div class="pure-u-1" >
{{searchCtrl.results.length}}
<div ng-repeat="track in searchCtrl.results" ng-include src="'templates/single-track-view.html'" >
</div>
</div>
</div>
我的控制器代码:
app.controller('SearchController',function(){
var searchCtrl = this;
searchCtrl.results = [];
searchCtrl.query = '';
this.search = function(query){
console.log(searchCtrl.query);
var processTracks = function(results){
console.log(results);
searchCtrl.results = results[0].tracks;
searchCtrl.results.push(results[1].tracks);
searchCtrl.query = '';
return results;
}
//search takes a DICTIONARY not a pure string
mopidy.library.search({"any": searchCtrl.query}).then(processTracks,console.error.bind(console));
}
});
使用AngularJS检查器时,我绝对可以看到searchCtrl.results在范围内更新并获得正确的结果。在我开始删除字符之前,视图根本不会更新。
编辑:来自promise的结果实际上是一系列响应。我从Mopidy(一个音乐播放器)打电话给api,阵列是来自不同音乐提供商的不同回应。
答案 0 :(得分:1)
调用$scope.$apply
存在风险,但摘要循环确实存在问题。
正确的方法是通过调用$q.when
来调用Angular中的调用:
app.controller('SearchController',function($q){ // note the $q here for promises
var searchCtrl = this;
searchCtrl.results = [];
searchCtrl.query = '';
this.search = function(query){
console.log(searchCtrl.query);
var processTracks = function(results){
console.log(results);
searchCtrl.results = results[0].tracks;
searchCtrl.results.push(results[1].tracks);
searchCtrl.query = '';
return results;
}
//$q.when assimilates a third party promise into Angular
$q.when(mopidy.library.search({"any": searchCtrl.query}))
.then(processTracks,console.error.bind(console));
}
});
如果我们仔细查看代码,我们会注意到.then
。
那个.then
是一个承诺 - 对并发的抽象是如何表明API调用的价值现已准备就绪。
Promise库,至少是体面的库运行在一个名为"Promises/A+"的规范上,告诉他们如何与彼此交互 - 所以Angular的promise库 - $q
- 可以无缝地使用mopidy.library
承诺
Angular的$ q承诺是hooked directly into the digest loop,因此将第三方承诺投射到Angular中会使其与摘要循环同步,而不是自己强制进行第二次摘要。
答案 1 :(得分:0)
除非你的track属性是一个数组,否则没有意义
searchCtrl.results = results[0].tracks;
searchCtrl.results.push(results[1].tracks);
如果它是一个数组,你通过重新定义它来打破ng-repeat和观察变量之间的联系。如果mopidy是一个外部库,你需要在更新结果变量后对你的更改进行$ pply
答案 2 :(得分:0)
正如其他人所指出的,这里的解决方案是打电话给$scope.$apply();
原因: 当你制作XHR时,它超出了角度的常规摘要周期,即当它更新所有用于双向数据绑定的侦听器时。调用$ apply,强制摘要以便更新所有收听模型。