使用ionic的时候,有这样的一个场景,需要对ion-radio使用ng-rapeat,以生成一个选项列表,并当选择选项的时候,检测值的改变。选项列表是放在一个ion-view中的,这其中涉及多层scope的嵌套:controller有一个顶层scope,ion-view在渲染的时候,会生成一个子scope,ng-repeat又会生成自己的scope,多个scope嵌套起来非常复杂,实现的时候搞得比较久,记录下结果:
1、通过$state配置视图的controller 时的写法:##
app.js配置:
1 2 3 4 5 6 7 8 9 10
| angular.module('starter',['ionic']) .config(function($stateProvider, $urlRouterProvider){ $stateProvider .state('floor',{ url: '/floor', templateUrl: 'templates/floor.html', controller: 'FloorCtrl' })
});
|
模板部分写法:
1 2 3 4 5 6 7 8 9
| <ion-view> <ion-content> <div> <ion-list> <ion-radio ng-model="a.floorModel" ng-repeat="floor in floorItems" value="{{floor}}">{{floor}}</ion-radio> </ion-list> </div> </ion-content> </ion-view>
|
controller部分:
1 2 3 4 5 6 7 8 9 10 11
| angular.module('starter').controller('FloorCtrl', function($scope){ $scope.a = {"floorModel":""}; $scope.floorItems = ['floorA', 'floorB'];
$scope.$watch("a.floorModel", function(newVal,oldVal){ console.log('floorNewVal:'+ newVal); if(newVal==oldVal){ return; } console.log('value change'); });
|
2、controller写在ion-content上可以减少一层scope
模板部分写法:
1 2 3 4 5 6 7 8 9
| <ion-view ng-controller="FloorCtrl"> <ion-content> <div> <ion-list> <ion-radio ng-model="$parent.floorModel" ng-repeat="floor in floorItems" value="{{floor}}">{{floor}}</ion-radio> </ion-list> </div> </ion-content> </ion-view>
|
controller部分:
1 2 3 4 5 6 7 8 9 10 11
| angular.module('starter').controller('FloorCtrl', function($scope){ $scope.floorModel = ''; $scope.floorItems = ['floorA', 'floorB'];
$scope.$watch(floorModel, function(newVal,oldVal){ console.log('floorNewVal:'+ newVal); if(newVal==oldVal){ return; } console.log('value change'); });
|
大坑
写模板的时候,ion-radio标签的value按照官网介绍作ng-value=”xxx”时,会有这样的bug:第一次选择时,总是选列表的最后一项,并且$watch只在值为数字的时候表现正常,按照angularJS的radio的value写法value=”xxx”,$watch就表现正常了,而其他页面却没有这个bug,目前实验多次均是这个结论,也算是个大坑了。也由此得到的教训:出现很奇葩的bug的时候,一定要仔细求证语句写法; 这不能怪本宝宝。
关于第二种写法,即controller写在ion-content上,如果没有用ng-repeat这种会生成child scope的用法时,就不用加$parent了;如果用了就必须加,因为嵌套了两层scope,而把controller写在ion-content上只消除一层scope嵌套。
小知识点
当$watch的第一个参数写成字符串不起作用时,可以这样写,第一个参数写成函数:
1
| $scope.$watch(function(){return $scope.a.floorModel}, function(newVal, oldVal){});
|