javascript - Angular ng-repeat View 在搜索后不会更新

标签 javascript angularjs promise

我正在尝试使用服务调用来更新结果数组,然后在 ng-repeat 中使用该结果数组。在表单提交上,我调用必要的服务,并通过 Promise 对象上的 .then() 连接我的回调。不幸的是,只有当我开始从文本输入中删除字符时, View 才会更新。然后它会显示正确的结果。

这是我的观点:

<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>

还有我的 Controller 代码:

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 在范围内更新为正确的结果。在我开始删除字符之前, View 不会更新。

编辑:从 promise 返回的结果实际上是一组响应。我从 Mopidy(音乐播放器)调用 api,该数组是来自不同音乐提供商的不同响应。

最佳答案

调用 $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));
    }

});

但是为什么它有效呢? $q 是什么?

如果我们仔细查看代码,我们会注意到.then

.then 是 promise (并发性抽象)如何发出 API 调用的值已准备就绪的信号。

Promise 库,至少是像样的库运行在名为 "Promises/A+" 的规范上它告诉他们如何相互交互 - 因此 Angular 的 Promise 库 - $q - 可以无缝地使用 mopidy.library Promise。

Angular 的 $q promise 是 hooked directly into the digest loop ,因此将第三方 Promise 转换为 Angular Promise 使其与摘要循环同步运行,而不是强制您自己执行第二个摘要。

关于javascript - Angular ng-repeat View 在搜索后不会更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24479141/

相关文章:

javascript - 当 Promise 状态被拒绝或解决时

javascript - Node.js/Javascript 多重递归 promise 在 View 中返回

javascript - 判断一个字符串是否由特定的字符集组成

javascript - 更新选项在 Ajax 和 Laravel 的帮助下根据其他 select 标签选择属性?

javascript - 控制程序的流程

javascript - 为什么在 $rootScope.$on 中需要 $rootScope.$apply?

JavaScript:设置背景图像的大小和文件夹中随机图像的不重复

javascript - 如何用 Angular.js 动态生成 DOM?

javascript - AngularJS:关于实例化服务

Javascript: promise 等待条件或在尝试次数后中止