使用AngularJS时解决的一些小问题

1. 设置select的ng-model,但未显示初始选项

解决方法:在ng-options中加上track by语句。
如:

<select class="form-control" ng-model="customerInfo.staffInCharge" 
                        ng-options="staffInCharge.name for staffInCharge in staffs track by staffInCharge.id">
                        </select>

参考了http://gurustop.net/blog/2014/01/28/common-problems-and-solutions-when-using-select-elements-with-angular-js-ng-options-initial-selection/

2. 想要实时获得一组checkbox中选中的对象list

解决方法:使用开源的checklist-model。
它的使用例子和源码在这里:http://vitalets.github.io/checklist-model/
要使用它,只要将下载的checklist-model.js放在你的js目录下,引用这个js,并在你的app的依赖里添加即可使用了。例如:

var app = angular.module("app", ["checklist-model"]);

使用场景例如:

<tbody>
                <tr ng-repeat="staff in staffs">
                    <td><input type="checkbox" checklist-model="selects.staffs" checklist-value="staff" 
                        ng-change="checkOrUncheck(checked, staff)"/></td>
                    <td><span class="glyphicon glyphicon-user" ng-show="staff.role == 1"></span></td>
                    <td ng-bind="staff.name"></td>
                    <td ng-bind="staff.mobile"></td>
                    <td ng-bind="staff.email"></td>
                    <td ng-bind="staff.leader"></td>
                    <td ng-bind="staff.position"></td>
                    <td>
                        <button class="btn btn-primary btn-sm" data-toggle="modal" data-target="#editStaff" ng-click="editIt(staff)">
                            <span class="glyphicon glyphicon-pencil"></span>
                        </button>
                        <button class="btn btn-default btn-sm" ng-click="unassociateIt(staff)">
                            <span class="glyphicon glyphicon-remove"></span>
                        </button>
                    </td>
                </tr>
            </tbody>

3. 对ng-repeat中的radio使用ng-model时失败

解决方法:要在radio的ng-model中使用$parent,例如:

<tr ng-repeat="staff in staffs">
                        <td><input type="radio" ng-model="$parent.chosenInCharge" ng-value="staff" name="chosen"/></td>
                        <td><span class="label label-info">{{staff.name}}</span></td>
                        <td><span class="label label-info">{{staff.mobile}}</span></td>
                    </tr>

这样,我们就能在chosenInCharge里得到选中的staff了,那我们怎么在Controller里使用chosenInCharge呢,有个简单的方法,就是将它作为按钮点击事件的参数传递进controller里。例如:

<button type="button" class="btn btn-primary" ng-click="confirmInCharge(chosenInCharge)">确定</button>

参考了这个网页:http://stackoverflow.com/questions/17674899/angularjs-model-not-updating-on-selection-of-radio-button-generated-by-ng-repe

4. ui-view嵌套路由的使用

在HTML文件里:

<div class="container" style="width:100%;" ng-controller="staffOperationController">
        <ul id="staffTab" class="nav nav-tabs">
            <li class="active"><a ui-sref="staffAndDept.associated">已关联</a>
            </li>
            <li><a ui-sref="staffAndDept.noleader">未选上级</a>
            </li>
            <li><a ui-sref="staffAndDept.unassociated">未关联</a>
            </li>
            <li><a ui-sref="staffAndDept.deleted">已解除关联</a>
            </li>
        </ul>
        <div ui-view></div>
</div>
<script>
$('#staffTab li').click(function (e) {
    e.preventDefault()
    $(this).tab('show')
})
</script>

我们定义了四个staffAndDept的子路由,它们将放在ui-view这个div里。紧接着的脚本作用是显示选择的tab。
接着,我们在app里这样使用:

SalesApp.config( function($stateProvider, $urlRouterProvider) {
    console.log("configuring router")
    $urlRouterProvider
        .when('/staffAndDept','/staffAndDept/associated')
        .when('','/staffAndDept/associated')
    $stateProvider          
        .state('staffAndDept', {
            url:'/staffAndDept',
            templateUrl: 'view/staffAndDept.html',
        })
        .state('staffAndDept.associated', {
            url:'/associated',
            templateUrl: 'view/associated.html',
        })
        .state('staffAndDept.noleader', {
            url:'/noleader',
            templateUrl: 'view/noleader.html',
        })
        .state('staffAndDept.unassociated', {
            url:'/unassociated',
            templateUrl: 'view/unassociated.html',
        })
        .state('staffAndDept.deleted', {
            url:'/deleted',
            templateUrl: 'view/deleted.html',
        })
}); 

在上面,我们使用$urlRouterProvider.when来指定一个默认的子路由,否则的话,当在父路由的时候,ui-view那个div就是空着的了。
参考了《AngularJS权威教程》第25章《AngularJS扩展精华》的25.3 ui-router的5 嵌套路由。

5. $http对params(当其中包含数组时) JSON化的问题

$http会自动对params里的数据进行JSON化,例如,我们定义:

$scope.oneMobile = {mobile:15021137613}
$http({
            url:'/svr/index.php?c=Mobile&a=UNamePart',
            method:'GET',
            params:{p2:$scope.oneMobile}
        }).success(function(response){  
        })

通过firefox的web控制台,我们可以看到它的url是:

http://sales.dev1.briwork.com/svr/index.php?c=Mobile&a=UNamePart&p2={"mobile":"15021137613"}

但是,当我们想要传递数组参数时,我们这样可能会这样做:

$scope.mobiles = [{mobile:15021137613},{mobile:12345678901}]
$http({
            url:'/svr/index.php?c=Mobile&a=UNamePart',
            method:'GET',
            params:{p2:$scope.mobiles}
        }).success(function(response){  
        })

但事实上,我们得到的请求的url是:

http://sales.dev1.briwork.com/svr/index.php?c=Mobile&a=UNamePart&p2={"mobile":"15021137613"}&p2={"mobile":"12345678901"}

而我希望的url应该是这样的:

http://sales.dev1.briwork.com/svr/index.php?c=Mobile&a=UNamePart&p2=[{"mobile":"15021137613"},{"mobile":"12345678901"}]

解决方法:既然$http的JSON化有问题,那我们就先将我们的数组JSON化,再作为参数传递进去。这里,我们就使用JSON.stringify()方法手动做JSON化。即:

$http({
            url:'/svr/index.php?c=Mobile&a=UNamePart',
            method:'GET',
            params:{p2:JSON.stringify($scope.mobiles)}
        }).success(function(response){  
        })

6. 需要使用angular.copy()而非直接赋值的一种情况

我在使用checklist-model时,写了常用的全选全不选,单选单不选的函数:

$scope.selects = {
            customers:[],
            numberOfSelectedCustomers:0
    }
    $scope.checkOrUncheckAll = function(checkAll) {
        if(checkAll){
            $scope.selects.customers = angular.copy($scope.customers)
            //如果这里写成
            //$scope.selects.customers = $scope.customers
            // 就会有一个bug,即在全选之后,在做单个的取消勾选时,在HTML页上,被取消勾选的那一行纪录就会消失(虽然刷新之后会再出现)
            $scope.selects.numberOfSelectedCustomers = $scope.customers.length
        } else {
            $scope.selects.customers = [] 
            $scope.selects.numberOfSelectedCustomers = 0
        }
    }
    $scope.checkOrUncheck = function(checked, customer) {
        var idx = $scope.selects.customers.indexOf(customer)
        if (idx >= 0 && !checked) {
            $scope.selects.customers.splice(idx, 1)
            --$scope.selects.numberOfSelectedCustomers
        }
        if (idx < 0 && checked) {
            $scope.selects.customers.push(customer)
            ++$scope.selects.numberOfSelectedCustomers
        }
        console.log($scope.selects.numberOfSelectedCustomers)
        console.log($scope.selects.customers)
    }

相应的HTML页是这样的:

<table class="table table-striped">
            <thead>
                <tr>
                    <th><input type="checkbox" ng-model="checkAll" ng-change="checkOrUncheckAll(checkAll)"/></th>
                    <th>客户名称</th>
                    <th>公司简称</th>
                    <th>负责人</th>
                    <th>客户等级</th>
                    <th>创建时间</th>
                    <th>操作2</th>
                </tr>
            </thead>
            <tbody>
                <tr ng-repeat="customer in customers | startFrom:currentPage*pageSize | limitTo:pageSize">
                    <td><input type="checkbox" checklist-model="selects.customers" checklist-value="customer" 
                        ng-change="checkOrUncheck(checked, customer)"/></td>
                    <td ng-bind="customer.name"></td>
                    <td ng-bind="customer.sname"></td>
                    <td ng-bind="customer.staff"></td>
                    <td ng-bind="customer.level"></td>
                    <td ng-bind="customer.ct"></td>
                    <td>
                        <button class="btn btn-default btn-sm" ng-click="deleteIt(customer)"
                        data-toggle="modal" data-target="#deleteCustomer">
                            <span class="glyphicon glyphicon-remove"></span>
                        </button>
                    </td>
                </tr>
            </tbody>
            <button class="btn btn-default" ng-disabled="currentPage==0" ng-click="currentPage = currentPage-1">上一页</button>
            {{currentPage+1}}/{{numberOfPages()}}
            <button class="btn btn-default" ng-disabled="currentPage >= numberOfPages()-1" ng-click="currentPage = currentPage+1">下一页</button>
        </table>

不使用angular.copy()造成的bug如上面注释所说。值得一提的是,上面的html中还有分页的功能。
ng-repeat时列表过长,需要分页,参考了这个网页http://stackoverflow.com/questions/11581209/pagination-on-a-list-using-ng-repeat


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值