GVKun编程网logo

angularjs – 有没有办法在AngularUI路由器中的任何子解析之前解析一个promise

14

针对angularjs–有没有办法在AngularUI路由器中的任何子解析之前解析一个promise这个问题,本篇文章进行了详细的解答,同时本文还将给你拓展angularjs–$httpissue–在

针对angularjs – 有没有办法在AngularUI路由器中的任何子解析之前解析一个promise这个问题,本篇文章进行了详细的解答,同时本文还将给你拓展angularjs – $http issue – 在md-autocomplete Angular Material中解析promise之前,不能返回值、angularjs – angular $q,如何链接在for循环内和之后的多个promises、angularjs – Angular promise在函数内解析但不在外部、angularjs – Angular ui-router:如何在解析子解析之前渲染父视图?等相关知识,希望可以帮助到你。

本文目录一览:

angularjs – 有没有办法在AngularUI路由器中的任何子解析之前解析一个promise

angularjs – 有没有办法在AngularUI路由器中的任何子解析之前解析一个promise

我在coffeescript中有2个州……
stateProvider.state  'test',...
    resolve:
        user: (LongRunning)->
            LongRunning.authenticate().then ->
                console.log("We are authenticated!")

stateProvider.state  'test.child',...
    resolve:
        other: (Afterauth)->
            Afterauth.soSomethingWithAuth().then ->
                console.log("We are done!")

当然这不起作用,因为在解析父级的auth方法之前启动了子解析.这意味着第二个函数将不会被验证并导致整个状态失败.

现在它不一定是状态路径的一部分,但它需要在调用resolve函数时完全完成.

在调用child中的方法之前,如何确保完全解析父函数?

坏(?)解决方案

我能够提出的一个答案是使用手动引导程序.然而,这是乏味的,因为我需要重新连接我的所有服务.无论如何我可以在Angular中做到吗?

你是使用AngularUI Router for Angular 2还是AngularJS?我认为AngularJS就是你使用coffeescript和AngularUI Router的事实.这是Angular标签而不是AngularJS.

无论如何在AngularUI路由器中,一个解析器可以依赖于另一个.像这样的东西:

function firstStep($stateParams,resolveStatus) {
   return $q.resolve();
 }

 resolve: {
   firstStep: firstStep,secondStep: ['firstStep',function (firstStep) {
   ...
   }]
 }

angularjs – $http issue – 在md-autocomplete Angular Material中解析promise之前,不能返回值

angularjs – $http issue – 在md-autocomplete Angular Material中解析promise之前,不能返回值

我在我的项目中使用Angular Material md-autocomplete.在那里我通过使用$http服务的ajax调用从服务主机获取建议列表.

Issue: $http issue – Values can’t be returned before a promise is
resolved in md-autocomplete Angular Material

My Requirement: I need an updated Suggestion List using remote data
sources in md-autocomplete Angular Material – Ajax $http service.

我使用了Angular Material link https://material.angularjs.org/latest/demo/autocomplete中提到的方法

源代码:

场景1:

HTML源代码:

<md-autocomplete flex required
    md-input-name="autocompleteField"
    md-no-cache="true"
    md-input-minlength="3"
    md-input-maxlength="18"
    md-selected-item="SelectedItem"
    md-search-text="searchText"
    md-items="item in querySearch(searchText)"
    md-item-text="item.country" Placeholder="Enter ID">
    <md-item-template>
        <span>
            <span md-highlight-text="searchText" md-highlight-flags="^i"> {{item.country}} </span>
    </md-item-template>
</md-autocomplete>

AngularJS脚本:

//bind the autocomplete list when text change
function querySearch(query) {
    var results = [];
    $scope.searchText = $scope.searchText.trim();
    if (query.length >=3) {
        results = LoadAutocomplete(query);
    }
    return results;
}

//load the list from the service call
function LoadAutocomplete(id) {
    var countryList = [];
    $http({
            method: "post",url: "https://www.bbminfo.com/sample.PHP",params: {
                token: id
            }
        })
        .success(function (response) {
            countryList = response.records;
        });

        return countryList;
}

场景2:

HTML与AngularJS源代码:

<!DOCTYPE html>
<html>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular-material.min.css">
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-animate.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-aria.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-messages.min.js"></script>

<!-- Angular Material Library -->
<script src="http://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular-material.min.js"></script>
<body>

<div ng-app="myApp" ng-controller="myCtrl"> 

<p>Person to Select:</p>

<md-autocomplete
          ng-disabled="isdisabled"
          md-no-cache="noCache"
          md-selected-item="selectedItem"
          md-search-text-change="searchTextChange()"
          md-search-text="searchText"
          md-selected-item-change="selectedItemChange(item)"
          md-items="item in Person"
          md-item-text="item.Name"
          md-min-length="0"
          placeholder="Which is your favorite Person?">
        <md-item-template>
          <span md-highlight-text="ctrl.searchText" md-highlight-flags="^i">{{item.country}}</span>
        </md-item-template>
        <md-not-found>
          No Person matching "{{searchText}}" were found.
        </md-not-found>
      </md-autocomplete>
      <br/>
</div>

<script>
    var app = angular.module('myApp',['ngMaterial']);

    app.controller('myCtrl',function ($scope,$http,$q) {

        $scope.searchText = "";
        $scope.Person = [];
        $scope.selectedItem = [];
        $scope.isdisabled = false;
        $scope.noCache = false;

        $scope.selectedItemChange = function (item) {
            alert("Item Changed");
        }
        $scope.searchTextChange = function () {

            $http({
                method: "POST",params: {
                    token: $scope.searchText
                }
            })
            .success(function (response) {
                $scope.Person = response.records;
            });
        }

    });
</script>
</body>
</html>

在场景1中,我使用该函数来获取已过滤的列表md-items =“querySearch(searchText)中的项目”.但是在场景2中,我使用了$scope变量md-items =“item in Person”

请参考快照

快照1:

在这里,我正在寻找印度人,但它显示了印度的结果.我在Firefox浏览器Firebug中调试了这个问题,看到上面显示的快照1,请求是通过POST方法为搜索词indian发送的,我得到了一个匹配项作为JSON对象的响应成功,这显示在底部SnapShot 1

The issue I find out in this case,the Values can’t be returned before
a promise is resolved

我试过的步骤:

案例1:我在UI md-items =“item in Person | filter:searchText”中使用了AngularJS过滤器,它提供了先前获取的远程数据的过滤列表,而不是当前获取的远程数据.在Backspacing文本框中的字符时,它会显示不正确的建议列表.

案例2:我尝试通过在$http服务中调用$scope.$apply()来更新UI中的更改,但它失败了.因为$http服务默认调用$scope.$apply(),显示它会抛出一个错误错误:[$rootScope:inprog] ….最后在这次尝试中我失败了.

情况3:我在函数中创建了一个函数,我手动调用$scope.$apply(),在我手动推送的函数中,将一个虚拟项加到$scope变量中,该变量在md-autocomplete中绑定.但是我在这次尝试中失败了.因为在这里我也得到了与快照中相同的输出.

function Ctrlm($scope) {
    $scope.messagetoUser = "You are done!";
    setTimeout(function () {
        $scope.$apply(function () {

            $scope.dummyCntry = [
                {
                    sno: 0,country: ""
                },];

            $scope.Person.push($scope.dummyCntry);

            var index = $scope.Person.indexOf($scope.dummyCntry);
            $scope.Person.splice(index,1);

        });
    },10);
}

案例4:我在$scope中使用了与“Case 3”相同的方法.$watchCollection.在这里我也遇到了挫折.

$scope.$watchCollection('Person',function (newData,oldDaata) {
    $scope.dummyCntry = [
                {
                    sno: 0,];

    newData.push($scope.dummyCntry);

    var index = newData.indexOf($scope.dummyCntry);
    newData.splice(index,1);
});

案例5:我使用jquery ajax调用而不是$http服务.在那里,我使用$scope.apply()手动更新UI.我再一次尝试失败了,这里也得到了相同的输出.

$scope.searchTextChange = function () {
    if (($scope.searchText != undefined) && ($scope.searchText != null)) {

        $.ajax({
            type: 'GET',url: "https://www.bbminfo.com/sample.PHP?token=" + $scope.searchText,success: function (response) {
                $scope.$apply(function () {
                    $scope.Person = response.records;
                });
            },error: function (data) {
                $scope.$apply(function () {
                    $scope.Person = [];
                });
            },async: true
        });


    } else {
        $scope.Person = [];
    }
}

In all the attempts I can’t able to fix the issue.

@georgeawg https://stackoverflow.com/users/5535245/georgeawg建议我发布一个新问题,他说,“写一个新问题,描述你实际上想要实现的目标,包括所需的行为,到目前为止你为解决问题所做的工作总结,以及你解决它的困难的描述.“

我之前发布的参考问题

邮报1:http://www.stackoverflow.com/questions/35624977/md-items-is-not-updating-the-suggesion-list-properly-in-md-autocomplete-angular

邮报2:http://www.stackoverflow.com/questions/35646077/manually-call-scope-apply-raise-error-on-ajax-call-error-rootscopeinprog

My Requirement: I need an updated Suggestion List using remote data
sources in Angular Material md-autocomplete – Ajax $http service.

请在这方面帮助我.

For Testing Purpose Use the following Source Code

对远程数据源使用以下URL:https://bbminfo.com/sample.php?token=ind

远程数据源URL包含国家/地区名称列表.

Directly Test the Code by click the below Run Code Snippet button.

使用AngularJS完整HTML源代码:

<!DOCTYPE html>
<html>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular-material.min.css">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-animate.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-aria.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-messages.min.js"></script>

<!-- Angular Material Library -->
<script src="http://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular-material.min.js"></script>
<body>

<div ng-app="myApp" ng-controller="myCtrl"> 

<p>Country to Select:</p>
<md-content>
<md-autocomplete
          ng-disabled="isdisabled"
          md-no-cache="noCache"
          md-selected-item="selectedItem"
          md-search-text-change="searchTextChange()"
          md-search-text="searchText"
          md-selected-item-change="selectedItemChange(item)"
          md-items="item in Person"
          md-item-text="item.country"
          md-min-length="0"
          placeholder="Which is your favorite Country?">
        <md-item-template>
          <span md-highlight-text="searchText" md-highlight-flags="^i">{{item.country}}</span>
        </md-item-template>
        <md-not-found>
          No Person matching "{{searchText}}" were found.
        </md-not-found>
      </md-autocomplete>
      </md-content>
      <br/>
</div>

<script>
    var app = angular.module('myApp',$q) {

        $scope.searchText = "";
        $scope.Person = [];
        $scope.selectedItem = [];
        $scope.isdisabled = false;
        $scope.noCache = false;

        $scope.selectedItemChange = function (item) {
            alert("Item Changed");
        }
        $scope.searchTextChange = function () {

            $http({
                method: "post",params: {
                    token: $scope.searchText
                }
            })
            .success(function (response) {
				$scope.Person = response.records;
            });
        }

    });
</script>
</body>
</html>
@KevinB https://stackoverflow.com/users/400654/kevin-b – 给出了如何实施的想法.我真的很感谢他……再一次感谢Kevin …

我得到了Exact解决方案,我需要什么.

源代码是

<!DOCTYPE html>
<html>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/angular_material/1.0.0/angular-material.min.css">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-animate.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-aria.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular-messages.min.js"></script>

<!-- Angular Material Library -->
<script src="http://ajax.googleapis.com/ajax/libs/angular_material/1.0.4/angular-material.min.js"></script>
<body>

<div ng-app="myApp" ng-controller="myCtrl"> 

<p>Country to Select:</p>
<md-content>
<md-autocomplete
          ng-disabled="isdisabled"
          md-no-cache="noCache"
          md-selected-item="selectedItem"
          md-search-text="searchText"
          md-items="item in searchTextChange(searchText)"
          md-item-text="item.country"
          md-min-length="0"
          placeholder="Which is your favorite Country?">
        <md-item-template>
          <span md-highlight-text="searchText" md-highlight-flags="^i">{{item.country}}</span>
        </md-item-template>
        <md-not-found>
          No Person matching "{{searchText}}" were found.
        </md-not-found>
      </md-autocomplete>
      </md-content>
      <br/>
</div>

<script>
    var app = angular.module('myApp',$q,GetCountryService) {

        $scope.searchText = "";
        $scope.Person = [];
        $scope.selectedItem = [];
        $scope.isdisabled = false;
        $scope.noCache = false;

        $scope.selectedItemChange = function (item) {
            //alert("Item Changed");
        }
        $scope.searchTextChange = function (str) {
			return GetCountryService.getCountry(str);
        }

    });
	
	app.factory('GetCountryService',function ($http,$q) {
        return {
            getCountry: function(str) {
                // the $http API is based on the deferred/promise APIs exposed by the $q service
                // so it returns a promise for us by default
				var url = "https://www.bbminfo.com/sample.PHP?token="+str;
                return $http.get(url)
                    .then(function(response) {
                        if (typeof response.data.records === 'object') {
                            return response.data.records;
                        } else {
                            // invalid response
                            return $q.reject(response.data.records);
                        }

                    },function(response) {
                        // something went wrong
                        return $q.reject(response.data.records);
                    });
            }
        };
    });
</script>
</body>
</html>

我在以下博客中简要介绍了md-autocomplete – http://www.increvcorp.com/usage-of-md-autocomplete-in-angular-material/

angularjs – angular $q,如何链接在for循环内和之后的多个promises

angularjs – angular $q,如何链接在for循环内和之后的多个promises

我想有一个for循环,每次迭代调用异步函数。

在for循环后,我想执行另一个代码块,但不是在for循环中的所有以前的调用已经解决之前。

我现在的问题是,for循环之后的代码块在所有异步调用完成之前执行,或者根本不执行。

代码部分与FOR循环和代码块之后(完整代码,请参阅fiddle):

[..]
function outerFunction($q,$scope) {
    var defer = $q.defer();    
    readSome($q,$scope).then(function() {
        var promise = writeSome($q,$scope.testArray[0])
        for (var i=1; i < $scope.testArray.length; i++) {
             promise = promise.then(
                 angular.bind(null,writeSome,$q,$scope.testArray[i])
             );                                  
        } 
        // this must not be called before all calls in for-loop have finished
        promise = promise.then(function() {
            return writeSome($q,"finish").then(function() {
                console.log("resolve");
                // resolving here after everything has been done,yey!
                defer.resolve();
            });   
        });        
    });   

    return defer.promise;
}

我创建了一个jsfiddle可以在这里找到http://jsfiddle.net/riemersebastian/B43u6/3/。

此时它看起来像执行顺序很好(见控制台输出)。

我的猜测是,这是因为每个函数调用立即返回,而不做任何真正的工作。我试图延迟defer.resolve与setTimeout但失败(即最后的代码块从未执行)。你可以在小提琴的outcommented块中看到它。

当我使用写入文件和从文件读取的真正的函数时,最后一个代码块在最后一个写操作完成之前执行,这不是我想要的。

当然,错误可能是在那些读/写函数之一,但我想验证这里发布的代码没有任何问题。

你需要使用的是 $q.all,它将许多promise组合成一个只有在所有的promise都解决了才解决。

在你的情况下,你可以做类似:

function outerFunction() {

    var defer = $q.defer();
    var promises = [];

    function lastTask(){
        writeSome('finish').then( function(){
            defer.resolve();
        });
    }

    angular.forEach( $scope.testArray,function(value){
        promises.push(writeSome(value));
    });

    $q.all(promises).then(lastTask);

    return defer.promise;
}

angularjs – Angular promise在函数内解析但不在外部

angularjs – Angular promise在函数内解析但不在外部

我有一个递归函数检查每半秒左右的一些数据.该函数返回一个promise.一旦找到数据,我想解决承诺并将数据作为分辨率传递.问题是,承诺不会在函数外部调用.then().这是小提琴: http://jsfiddle.net/btyg1u0g/1/.

这是小提琴代码:

服务:

myApp.factory('myService',function($q,$timeout) {

    var checkStartTime = false;
    var checkTimeout = 30000;

    function checkForContent() {

        var deferred = $q.defer();

        // simulating an $http request here
        $timeout(function () {

            console.log("Checking...");

            if (!checkStartTime) checkStartTime = new Date();

            // this would normally be 'if (data)'
            if ((new Date()) - checkStartTime > 3000) {
                deferred.resolve("Finished check");
                checkStartTime = false; // reset the timeout start time
            } else {
                // if we didn't find data,wait a bit and check again
                $timeout(function () {
                    checkForContent();
                },400);
            }

        },5);

        // then is called in here when we find data
        deferred.promise.then(function(message) {
             console.log("Resolved inside checkForContent");
        });

        return deferred.promise;

    }

    return {
        runcheck: function() {
            return checkForContent()
        }
    }
});

控制器:

myApp.controller('MyCtrl',function ($scope,myService) {
    $scope.name = 'Superhero';

    // then is never called
    myService.runcheck()
    .then(function (message) {
        console.log("Resolved outside checkForContent");
    });

});

解决方法

查看 this fiddle.

out $$timeout命名为可以从内部调用.

$timeout(function inner() {
  // ...

然后像这样递归调用它:

$timeout(function () {
  inner();
},400);

angularjs – Angular ui-router:如何在解析子解析之前渲染父视图?

angularjs – Angular ui-router:如何在解析子解析之前渲染父视图?

考虑以下ui-router设置:

的index.html

<div ui-view></div>

ui-router配置

$stateProvider
  .state('search',{
    abstract: true,url: '/search',views: {
      '@': {
        templateUrl: 'main.html'
      }
    }
  })
  .state('search.results',{
    url: '/results',views: {
      ...
    },resolve: {
      data: function() {
        ...
      }
    }
  })

当我导航到search.results时,在解析resolve之前不会呈现main.html.

ui-router中是否有一种方法可以在解析子解析之前呈现父视图?

Another related question

解决方法

正如评论中所提到的,使用resolve的目的是防止在加载数据之前发生状态更改.您显然不希望出现这种行为,因为您希望在加载“数据”之前进入状态并呈现视图的一部分.解决方案是在控制器中加载“数据”而不是使用resolve.如果控制器中存在依赖于“数据”的逻辑,则只需将该逻辑移动到回调中.

今天关于angularjs – 有没有办法在AngularUI路由器中的任何子解析之前解析一个promise的介绍到此结束,谢谢您的阅读,有关angularjs – $http issue – 在md-autocomplete Angular Material中解析promise之前,不能返回值、angularjs – angular $q,如何链接在for循环内和之后的多个promises、angularjs – Angular promise在函数内解析但不在外部、angularjs – Angular ui-router:如何在解析子解析之前渲染父视图?等更多相关知识的信息可以在本站进行查询。

本文标签: