2014-06-28 58 views
1

我无法使用AngularJSui.router

我有一个应用程序,其中基本上是一个用户写信息,发送到服务器,当服务器回答我改变当前状态为通道列表。

我的问题是,通过使用asynchroneus系统我失去改变目前的状态,没有任何错误的能力,演示:

下面演示的是一个这是确定的,因为它不使用asynchroneus系统(参见控制台):

代码: 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的工作吗?

回答

2

你的演示无法正常工作的原因是超时,当你从angulars知识中引起变化时,它很简单,角度保持不知道发生的变化,因此它不会更新。

解决方案是使用角度的方式来做到这一点。 angular提供$timeout服务。

阅读更多的在这里:https://docs.angularjs.org/api/ng/service/ $超时

工作(固定异步演示这里):http://jsfiddle.net/f9rSQ/2/

PS你应该总是使用角度的方式或NG-*指令来处理异步的变化之类的按钮点击事件监听器不会触发,如果你通过纯JavaScript来做它们。为了让它们起火,你可以强制角度运行一个$digest周期,当你使用ng-click$http等时,实际上发生的是实际发生的情况。