AngularJS + UI-Router:控制器更新后ng-model未同步至视图问题
问题原因分析
你遇到的这个问题核心在于 ui-router切换视图时,同一个控制器会被重新实例化。也就是说,View1里的ctrl1和View2里的ctrl1是两个完全独立的控制器实例,它们的$scope对象也是各自独立的。
当你在View1的goToForm方法里更新$scope.selectedList.name时,这个值只存在于View1对应的控制器实例的作用域中。跳转到View2后,系统会创建一个全新的ctrl1实例,它的$scope.selectedList是初始的空对象,所以输入框自然显示为空——控制台打印的是旧实例里的值,和新实例没关系。
解决方案
下面提供两种常用且规范的解决方法:
方法1:使用单例服务共享数据
AngularJS的服务是单例模式,所有控制器注入的都是同一个服务实例,非常适合用来跨视图/控制器共享数据。
步骤1:创建共享数据服务
angular.module('yourAppName') .service('SharedData', function() { // 这里存放需要共享的数据 this.selectedList = { name: "" }; });
步骤2:在控制器中注入并使用服务
angular.module('yourAppName') .controller('ctrl1', function($scope, $state, SharedData) { // 把$scope的selectedList绑定到服务的对象上 $scope.selectedList = SharedData.selectedList; $scope.goToForm = function(e) { // 更新服务里的对象属性 $scope.selectedList.name = e.name; $state.go('view2'); console.log(e); // 此时服务里的name已经更新 }; });
这样不管控制器被实例化多少次,$scope.selectedList始终引用服务里的同一个对象,View2的输入框就能正确显示更新后的值了。
方法2:通过ui-router的$stateParams传递参数
如果数据比较简单,也可以直接通过路由参数传递值,不需要额外的服务。
步骤1:配置路由参数
angular.module('yourAppName') .config(function($stateProvider) { $stateProvider .state('view1', { url: '/view1', templateUrl: 'view1.html', controller: 'ctrl1' }) .state('view2', { url: '/view2', templateUrl: 'view2.html', controller: 'ctrl1', // 定义路由参数,允许为空 params: { name: null } }); });
步骤2:跳转时传递参数并在控制器中接收
angular.module('yourAppName') .controller('ctrl1', function($scope, $state, $stateParams) { // 初始化selectedList,优先取路由参数里的值 $scope.selectedList = { name: $stateParams.name || "" }; $scope.goToForm = function(e) { // 跳转时携带参数 $state.go('view2', { name: e.name }); console.log(e); }; });
这种方法适合传递简单的字符串/数值类型数据,不需要维护全局的共享对象。
内容的提问来源于stack exchange,提问作者user3761308
相关产品推荐
相关产品推荐

