簡體   English   中英

帶有ui.router $ state的AngularJS在異步時不起作用

[英]AngularJS with ui.router $state not working when async

我在使用AngularJSui.router時遇到問題

我有一個應用程序,基本上用戶在其中寫信息,然后發送到服務器,並且當服務器回答時,我將當前狀態更改為頻道列表。

我的問題是,通過使用異步系統,我無法更改demos的當前狀態,而不會出現任何錯誤:

以下演示是可以的演示,因為它不使用異步系統(請參閱控制台):

代碼: http//jsfiddle.net/dievardump/x2tMT/

完整的演示: http : //jsfiddle.net/dievardump/x2tMT/embedded/result/

這是一個不正確的選項(請參閱控制台)。

代碼: http//jsfiddle.net/dievardump/f9rSQ/

完整的演示: http : //jsfiddle.net/dievardump/f9rSQ/embedded/result/

這兩個示例之間唯一的區別是在狀態“ platform.channels”的聲明中:

console.log('goes to platform.game');
$state.go('platform.game', {
    type: 'gameType',
    id: 1
});

VS

setTimeout(function () {
    console.log('should go to platform.game');
    $state.go('platform.game', {
        type: 'gameType',
        id: 1
    });
}, 1000);

完整的演示易於導入本地:

工作方式:

<div ui-view></div>
<script>


var myApp = angular.module('myApp', ['ui.router']);
myApp.config(function($stateProvider, $urlRouterProvider) {
        $urlRouterProvider.otherwise("/signin");

        $stateProvider
            .state('platform', {
                url: '/platform',
                data: {
                    permissions: ['auth']
                },
                template: "<section class='platform'>platform<div ui-view></div></section>",
                controller: function($state) {
                    console.log('platformController');
                }
            });
});

myApp.config(function($stateProvider, $urlRouterProvider) {
    $stateProvider
        .state('signin', {
            url: "/signin",
            template: "<section id='connect' class='connect'><form name='connection' action='' ng-submit='login(connection)'><input placeholder='Choose a nickname' ng-model='nickname' autocomplete='off' /><button><span>Send</span></button></form><p class='error' ng-show='error != null'>{{error}}</p></section>",
            controller: function($scope, $state) {
                $scope.error = null;
                $scope.nickname = null;

                $scope.login = function(form) {
                    var value = $scope.nickname.replace(/[^a-zA-Z0-9]/g, '');
                    if (value.length >= 3) {
                        $state.go('platform.channels');
                    } else {
                        $scope.error = 'only characters and numbers. length must be >= 3';
                    }
                }
            }
        });
});

myApp.config(function($stateProvider, $urlRouterProvider) {

    $stateProvider.state('platform.channels', {
        url: "/channels",
        template: "<section id='channels' class='channels'>channels</section>",
        controller: function($state) {
            console.log('channelController');
            console.log('goes to platform.game');
            $state.go('platform.game', {
                type: 'gameType',
                id: 1
            });
        }
    })
});

myApp.config(function($stateProvider, $urlRouterProvider) {
    $stateProvider.state('platform.game', {
            url: "/game/:type/:id",
            template: "<section id='game' class='game'>game</section>",
            controller: function() {
                console.log('gameController');
            }
        });
});


angular.bootstrap(document, ['myApp']);
</script>

不工作:

<div ui-view></div>
<script>


var myApp = angular.module('myApp', ['ui.router']);
myApp.config(function($stateProvider, $urlRouterProvider) {
        $urlRouterProvider.otherwise("/signin");

        $stateProvider
            .state('platform', {
                url: '/platform',
                data: {
                    permissions: ['auth']
                },
                template: "<section class='platform'>platform<div ui-view></div></section>",
                controller: function($state) {
                    console.log('platformController');
                }
            });
});

myApp.config(function($stateProvider, $urlRouterProvider) {
    $stateProvider
        .state('signin', {
            url: "/signin",
            template: "<section id='connect' class='connect'><form name='connection' action='' ng-submit='login(connection)'><input placeholder='Choose a nickname' ng-model='nickname' autocomplete='off' /><button><span>Send</span></button></form><p class='error' ng-show='error != null'>{{error}}</p></section>",
            controller: function($scope, $state) {
                $scope.error = null;
                $scope.nickname = null;

                $scope.login = function(form) {
                    var value = $scope.nickname.replace(/[^a-zA-Z0-9]/g, '');
                    if (value.length >= 3) {
                        $state.go('platform.channels');
                    } else {
                        $scope.error = 'only characters and numbers. length must be >= 3';
                    }
                }
            }
        });
});

myApp.config(function($stateProvider, $urlRouterProvider) {

    $stateProvider.state('platform.channels', {
        url: "/channels",
        template: "<section id='channels' class='channels'>channels</section>",
        controller: function($state) {
            console.log('channelController');
            setTimeout(function () {
                console.log('should go to platform.game');
                $state.go('platform.game', {
                    type: 'gameType',
                    id: 1
                });
            }, 1000);
        }
    })
});

myApp.config(function($stateProvider, $urlRouterProvider) {
    $stateProvider.state('platform.game', {
            url: "/game/:type/:id",
            template: "<section id='game' class='game'>game</section>",
            controller: function() {
                console.log('gameController');
            }
        });
});


angular.bootstrap(document, ['myApp']);
</script>

$ state.go在setTimeout中不起作用的任何原因?

您的演示無法正常工作的原因是超時,它很簡單,當您導致角度知識發生變化時,角度不了解發生的變化,因此不會更新。

解決方案是使用角度方式進行此操作。 angular提供$timeout服務。

在此處閱讀更多信息: https : //docs.angularjs.org/api/ng/service/ $ timeout

工作(此處已修復了異步演示): http : //jsfiddle.net/f9rSQ/2/

PS,您應該始終使用angular的方式或ng- *指令來處理異步更改,如果您通過純JavaScript進行操作,例如按鈕單擊事件偵聽器等將不會觸發。 為了使它們開火,您可以強制angular運行$digest循環,這是在使用ng-click$http等時以更清潔的方式實際發生的情況。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM