angularjs 学习小结

1.过滤器的使用 

<!DOCTYPE html>
<html>
    <head>
        <meta charset="{CHARSET}">
        <title></title>
        <script src="http://cdn.static.runoob.com/libs/angular.js/1.4.6/angular.min.js"></script>
    </head>
    <body ng-app="myApp" ng-controller="myTestCtrl">
       <!--<button ng-click="add()">Add Item</button>
       <ul>
            <li ng-repeat="item in arr1">{{item}}</li>
       </ul> 
       <ul>
            <li ng-repeat="childArr in arr3 track by $index">
                {{$index}}
                <ul>
                  <li ng-repeat="item in childArr track by $index">{{item}}</li>    
                </ul>
            </li>
       </ul>
       -->
       <ul>
             <li ng-repeat="item in arr2 track by $index">{{ item }}</li>
       </ul>
    </body>
</html>
<script>
angular.module('common',[]).filter('unique',function(){
    return function(arr)
    {
        var result = [], hash = {};
        for (var i = 0, elem; (elem = arr[i]) != null; i++) {
        if (!hash[elem]) {
        result.push(elem);
        hash[elem] = true;
        }
        }
        return result;
    };
});  
var app = angular.module("myApp",['common']);
app.controller("myTestCtrl", ['$scope','$filter',function($scope,$filter) {
    /*$scope.tom = {
          name: "Tom",
          gender: 1
    };
    $scope.formatGender = function(gender) {
        if (gender == 0) {
            return "女";
        }
        if (gender == 1){
            return "男";
        }
     };
     
     $scope.abs = function(number){
         return Math.abs(number);
     };
     $scope.arr1= [1,2,3];
     $scope.add = function(){
         $scope.arr1.push($scope.arr1.length +1);
     };
     $scope.arr3 = [
         [11,12,13],
         [21,22,23],
         [31,32,33],
     ];
     */
     debugger;
     $scope.arr2 = [1,1,3];
     $scope.arr2 = $filter("unique")($scope.arr2);

 }]);
</script>

filter 全匹配: <div ng-repeat="item in resultList | filter:{Status:‘test’}:true"></div> 返回resultList 中Status='test' 的结果 

 参考:http://docs.ngnice.com/api/ng/filter/filter

2.angularjs radio 默认选中

添加ng-checked="1"
<input type="radio" ng-model="sel_course" value="1" ng-checked="1" />

这样是不行的,实际上需要需要后台初始化数据为1

3.angularjs 的模型无法绑定到隐藏域(input hidden)

描述一下问题:

在操作表单中的隐藏域的时候发现angularjs的模型无法绑定,比如:

<input type="hidden" name="someData" ng-model="data" />
在网上找到了解决办法,特意记录;原文:http://stackoverflow.com/questions/18446359/angularjs-does-not-send-hidden-field-value

这种通常情况下data一直无法取到值;

有以下几种解决办法:

1).<input type="text" name="someData" ng-model="data" style="display: none;"/>

2).<input type="hidden" name="someData" value="{{data}}" />

3).<input type="hidden" name="someData" ng-value="data" />

参考:http://www.cnblogs.com/nyviva/p/4347706.html 

 4.如何在angular把DOM加载完成后再调用指定函数   

首先,你不应该将jquery插件和angular混用,这样做的话就会出现许多你现在这样要处理的麻烦。

正确的做法是,你写一个directive,来完成你的插件需要做的事情,当然也可以去github上找一个合适的。

然后就你的问题本身,你需要在ng-repeat 结束以后 触发你的函数

可以参考这里的说法
 https://stackoverflow.com/questions/15207788/calling-a-function-when-ng-repeat-has-finished

var module = angular.module('testApp', [])
.directive('onFinishRender', function ($timeout) {
    return {
        restrict: 'A',
        link: function (scope, element, attr) {
            if (scope.$last === true) {
                $timeout(function () {
                    scope.$emit('ngRepeatFinished');
                });
            }
        }
    }
});

在controller 中 监听

$scope.$on('ngRepeatFinished', function (ngRepeatFinishedEvent) {
    //you also get the actual event object
    //do stuff, execute functions -- whatever...
});

在页面上绑定

<div ng-repeat="item in items" on-finish-render="ngRepeatFinished">
  <div>{{item.name}}}<div>
</div>

他的做法其实也就是用一个directive 来监听 ng-repeat 是否结束。

5.Angulajs学习 http://www.cnblogs.com/zhili/p/AngularJSQuickStart.html

6.Anguarjs 格式化 {{Today | date:'yyyy年MM月dd日' }}

7.angularJS Provider、factory、service详解及实例代码 

 8.angularjs 去掉验证 $scope.表单名称.文本名称.$setValidity("自定义属性",true);    

$scope.personeditform.PersonNumber.$setValidity('idcard', true);
var $elem = angular.element("#PersonNumber");
$elem.removeClass("error").addClass("valid");
$elem.popover('hide');
$elem.closest("div").find(".popover ").hide();

 判断表单字段是否验证 , var result =  $scope.personeditform.testId.$valid,personeditform为表单名称, result 为true 验证成功;如为false 验证失败。

9.自定义指令 如,<lable-person ng-model="personID"></lable-person>,获取属性的值 scope.$parent.$eval(attrs["ngModel"]),具体代码如下:

angular.module("testComponent")
    .directive("lablePerson", ['resourceFactory', '$filter', function (resourceFactory, $filter) {
        return {
            resctict: "A",
            require: 'ngModel',
            scope: {
                callbackFn: "&callback"
            },
            templateUrl: "/test/lablePerson/lablePerson.html",
            link: function (scope, element, attrs) {
                var personRes = resourceFactory.getResource("PersonInfoRes");
                scope.personInfo = {};
                scope.getPersonInfo = function (id) {
                    personRes.get({ id: id }).$promise.then(function (data) {
                        if (data.IsSuccess && data.Data != null) {
                            angular.copy(data.Data, scope.personInfo);
                            scope.personInfo.Birthdate = $filter("ageFormat")(scope.personInfo.Birthdate);
                        }
                    });
                    scope.callbackFn({ personInfo: scope.personInfo });//回调函数
                }
                var id = scope.$parent.$eval(attrs["ngModel"]);
                if (id) {
                    scope.getPersonInfo(id);
                }
            }
        }
    }]);

 10.AngularJS操作DOM——angular.element

AngularJS操作DOM——angular.element
addClass()-为每个匹配的元素添加指定的样式类名
after()-在匹配元素集合中的每个元素后面插入参数所指定的内容,作为其兄弟节点
append()-在每个匹配元素里面的末尾处插入参数内容
attr() - 获取匹配的元素集合中的第一个元素的属性的值
bind() - 为一个元素绑定一个事件处理程序
children() - 获得匹配元素集合中每个元素的子元素,选择器选择性筛选
clone()-创建一个匹配的元素集合的深度拷贝副本
contents()-获得匹配元素集合中每个元素的子元素,包括文字和注释节点
css() - 获取匹配元素集合中的第一个元素的样式属性的值
data()-在匹配元素上存储任意相关数据
detach()-从DOM中去掉所有匹配的元素
empty()-从DOM中移除集合中匹配元素的所有子节点
eq()-减少匹配元素的集合为指定的索引的哪一个元素
find() - 通过一个选择器,jQuery对象,或元素过滤,得到当前匹配的元素集合中每个元素的后代
hasClass()-确定任何一个匹配元素是否有被分配给定的(样式)类
html()-获取集合中第一个匹配元素的HTML内容
next() - 取得匹配的元素集合中每一个元素紧邻的后面同辈元素的元素集合。如果提供一个选择器,那么只有紧跟着的兄弟元素满足选择器时,才会返回此元素
on() - 在选定的元素上绑定一个或多个事件处理函数
off() - 移除一个事件处理函数
one() - 为元素的事件添加处理函数。处理函数在每个元素上每种事件类型最多执行一次
parent() - 取得匹配元素集合中,每个元素的父元素,可以提供一个可选的选择器
prepend()-将参数内容插入到每个匹配元素的前面(元素内部)
prop()-获取匹配的元素集中第一个元素的属性(property)值
ready()-当DOM准备就绪时,指定一个函数来执行
remove()-将匹配元素集合从DOM中删除。(同时移除元素上的事件及 jQuery 数据。)
removeAttr()-为匹配的元素集合中的每个元素中移除一个属性(attribute)
removeClass()-移除集合中每个匹配元素上一个,多个或全部样式
removeData()-在元素上移除绑定的数据
replaceWith()-用提供的内容替换集合中所有匹配的元素并且返回被删除元素的集合
text()-得到匹配元素集合中每个元素的合并文本,包括他们的后代
toggleClass()-在匹配的元素集合中的每个元素上添加或删除一个或多个样式类,取决于这个样式类是否存在或值切换属性。即:如果存在(不存在)就删除(添加)一个类
triggerHandler() -为一个事件执行附加到元素的所有处理程序
unbind() - 从元素上删除一个以前附加事件处理程序
val()-获取匹配的元素集合中第一个元素的当前值
wrap()-在每个匹配的元素外层包上一个html元素

以removeClass为例:

HTML:
<div id="testID" class="test1">
<img id="testID2" class="test2" alt="" src="some-image.gif" />
</div>
JS:

angular.element('#testID2').find(’.test2‘).removeClass('.test3');

10. Angularjs 异步调用后台webapi,实现echart柱形图

  echarts 官方文档  http://echarts.baidu.com/option.html#title 

 1). echarts 通过angularjs异步调用获取y轴和x轴的数据

var CalculationDate = function(now, addDays) {
    var nowData = new Date(now);
    nowData = nowData.valueOf();
    nowData = nowData - addDays * 24 * 60 * 60 * 1000;
    nowData = new Date(nowData);
    return nowData.getFullYear() + "-" + (nowData.getMonth() + 1) + "-" + nowData.getDate();
}

$scope.Data = {
    BloodPressureData: { xData: [], yData: [], count: 0 },
    SugarPressureData: { xData: [], yData: [], count: 0 },
    IndexDetectDataList: []
};

$scope.BloodyDataMax = 0;
$scope.SugaryDataMax = 0;
$scope.BloodyDataAvg;
$scope.SugaryDataAvg;

var date = new Date();
$scope.EndTime = date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate();
$scope.BeginTime = CalculationDate($scope.EndTime, 30);
var bloodBIChart = echarts.init(document.getElementById('BloodBIChart'));
var bloodPressureOpt = {
    color: ['#29ccbf'],
    title: {
        text: ''
    },
    tooltip: {
        trigger: 'axis'
    },
    legend: {
        data: ['血压监测人次']
    },
    grid: {
        left: '10%',
        bottom: '35%',
        containLabel: true
    },
    toolbox: {
        feature: {
            //   saveAsImage: {}
        }
    },
    xAxis: {
        type: 'category',

        axisLabel: {
            interval: 0,
            rotate: 40
        },
        boundaryGap: false,
        data: []

    },
    yAxis: {
        type: 'value',
        name: '',
        //最小是多少,最大是多少,默认一次增加多少
        min: 0,
        max: 40,
        interval: 4,  //默认一次增加多少
        axisLabel: {
            formatter: '{value}',
            textStyle: {
                fontSize: 16
            }
        }
    },
    series: [
        {
            name: '血压监测人次',
            type: 'line',
            data: []
        }
    ]
};
bloodBIChart.setOption(bloodPressureOpt);
bloodBIChart.showLoading();
biIndexDetectDataRes.get({ 'Data.BeginTime': $scope.BeginTime, 'Data.EndTime': $scope.EndTime, 'CurrentPage': 1, 'PageSize': 0 }, function (data) {
    bloodBIChart.hideLoading();
    $scope.Data.BloodPressureData.xData.length = 0;
    $scope.Data.BloodPressureData.yData.length = 0;
    $scope.Data.BloodPressureData.count = 0;
    if (data.IsSuccess && data.Data) {
        if (data.Data.length > 0) {
            $scope.BloodyDataMax = data.Data[0].DayBloodPressureNum;
        }
        for (var i = 0; i < data.Data.length; i++) {
            var obj = data.Data[i];
            $scope.Data.BloodPressureData.xData.push(obj.MonitorDate.substring(0, 10));
            $scope.Data.BloodPressureData.yData.push(obj.DayBloodPressureNum);
            $scope.Data.BloodPressureData.count += obj.DayBloodPressureNum;
            if (obj.DayBloodPressureNum > $scope.BloodyDataMax) {
                $scope.BloodyDataMax = obj.DayBloodPressureNum;
            }
        }

        $scope.BloodyDataMax = $scope.BloodyDataMax == 0 ? 40 : $scope.BloodyDataMax;
        $scope.BloodyDataAvg = $scope.BloodyDataMax / 10;

        //血压监测人次
        var bloodPressureOption = {
            xAxis: {
                type: 'category',

                axisLabel: {
                    interval: 0,
                    rotate: 40
                },
                boundaryGap: false,
                data: $scope.Data.BloodPressureData.xData

            },
            yAxis: {
                type: 'value',
                name: '',
                //最小是多少,最大是多少,默认一次增加多少
                min: 0,
                max: $scope.BloodyDataMax,
                interval: $scope.BloodyDataAvg,  //默认一次增加多少
                axisLabel: {
                    formatter: '{value}',
                    textStyle: {
                        fontSize: 16
                    }
                }
            },
            series: [
                {
                    name: '血压监测人次',
                    type: 'line',
                    data: $scope.Data.BloodPressureData.yData
                }
            ]
        };
        bloodBIChart.setOption(bloodPressureOption);
        $scope.BloodyDataMax = 0;
    }
});
JS

 2).angularjs 调用后台数据,显示echart柱形图

 a.后台代码

#region
 public class PhysicalExaminationChart
{
    /// <summary>
    /// 检查值
    /// </summary>
    public decimal Value { get; set; }

    /// <summary>
    /// 体检时间
    /// </summary>
    public DateTime? ExamTime { get; set; }
}
/// <summary>
/// 
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
public BaseResponse<Dictionary<string, List<PhysicaExamChart>>> GetPhysicalExamDataChart(BaseRequest<PhysicalExamFilter> request)
{
    BaseResponse<Dictionary<string, List<PhysicaExamChart>>> response = new BaseResponse<Dictionary<string, List<PhysicaExamChart>>> { Data = new Dictionary<string, List<PhysicaExamChart>>() };
    if (request == null || request.Data == null || string.IsNullOrWhiteSpace(request.Data.Type))
    {
        return response;
    }
    var indexCodes = request.Data.Type.Split(',');
    int len = indexCodes.Length;
    if (len == 0)
    {
        return response;
    }
    var indexIds = indexCodes.ToList();

    foreach (var id in indexIds)
    {
        response.Data.Add(id, new List<PhysicaExamChart>());
    }

    var physicalExaminationRepository = unitOfWork.GetRepository<PhysicalExam>().dbSet;

    string indexCodeBMI = "010001010004";
    if (indexIds.Contains(indexCodeBMI))
    {
        #region BMI = 体重(kg)/身高(m)²
        //身高
        const string indexCodeHeight = "010001";
        //体重
        const string indexCodeWeight = "010002";
        var result = (from pe in physicalExaminationRepository
                      join pei in unitOfWork.GetRepository<IndexItem>().dbSet.Where(t => !t.IsDeleted)
                      on pe.ExaminationID equals pei.ExaminationID
                      join scim in unitOfWork.GetRepository<IndexManage>().dbSet.Where(t => !t.IsDeleted)
                      on pei.IndexManageID equals scim.IndexManageID
                      where pe.PersonID == request.Data.PersonID && !pe.IsDeleted && (indexCodeHeight.Contains(scim.IndexCode) || indexCodeWeight.Contains(scim.IndexCode))
                      select new
                      {
                          ExaminationID = pei.ExaminationID,
                          IndexCode = scim.IndexCode,
                          PhysicalExamTime = pe.PhysicalExamTime,
                          CheckValue = pei.CheckValue,
                      }).OrderBy(t => t.PhysicalExamTime).Take(14).ToList();
        List<PhysicaExamChart> dataResult = new List<PhysicaExamChart>();
        if (result != null && result.Any())
        {
            var resultHeight = result.Where(t => t.IndexCode == indexCodeHeight).OrderBy(t => t.PhysicalExamTime).Take(7).ToList();
            var resultWeight = result.Where(t => t.IndexCode == indexCodeWeight).OrderBy(t => t.PhysicalExamTime).Take(7).ToList();

            if (resultHeight != null && resultHeight.Any())
            {
                foreach (var item in resultHeight)
                {
                    var id = item.ExaminationID;
                    decimal weight = 0M;
                    if (id > 0)
                    {
                        var weigitInfo = resultWeight.FirstOrDefault(p => p.ExaminationID == id);
                        weight = (weigitInfo!=null &&  !string.IsNullOrEmpty(weigitInfo.CheckValue)  
                            && weigitInfo.CheckValue.ToDecimalZero() > 0M) ? (decimal)weigitInfo.CheckValue.ToDecimalZero() : 0M;
                    }

                    decimal? BMI = 0M;
                    if ( !string.IsNullOrEmpty(item.CheckValue)  && item.CheckValue.ToDecimalZero() > 0M)
                    {
                        var height = item.CheckValue.ToDecimalZero() / 100;
                        if (height != 0M)
                        {
                            //体重/身高的平方
                            BMI = weight / (height * height);
                        }
                    }

                    
                    foreach (var itemid in indexIds)
                    {
                        var firstOrDefault = new PhysicaExamChart()
                        {
                            Value = BMI.HasValue ? Math.Round(BMI.Value, 2) : 0M,
                            ExamTime = item.PhysicalExamTime
                        };
                        response.Data[itemid].Add(firstOrDefault);
                    }
                }
            }
        }

        #endregion
    }
    else
    {
        #region 血压(舒张压:2000002,收缩压:2000001)和空腹血糖:2000004
        var result = (from pe in physicalExaminationRepository
                      join pei in unitOfWork.GetRepository<IndexItem>().dbSet.Where(t => !t.IsDeleted)
                      on pe.ExaminationID equals pei.ExaminationID
                      join scim in unitOfWork.GetRepository<IndexManage>().dbSet.Where(t => !t.IsDeleted)
                      on pei.IndexManageID equals scim.IndexManageID
                      where pe.PersonID == request.Data.PersonID && !pe.IsDeleted && indexIds.Contains(scim.IndexCode)
                      select new
                      {
                          PhysicalExamTime = pe.PhysicalExamTime,
                          CheckValue = pei.CheckValue,
                          IndexCode = scim.IndexCode,
                      }).OrderBy(t => t.PhysicalExamTime).Take(7).ToList();

        if (result != null && result.Any())
        {
            foreach (var item in result)
            {
                foreach (var indeCode in indexIds)
                {
                    if (item.IndexCode == indeCode)
                    {
                        var firstOrDefault = new PhysicaExamChart() { Value = !string.IsNullOrEmpty(item.CheckValue)  ? 
                            (decimal)item.CheckValue.ToDecimalZero() : 0M, ExamTime = item.PhysicalExamTime };
                        response.Data[indeCode].Add(firstOrDefault);
                    }
                }
            }
        }
        #endregion
    }
    return response;
}
View Code

b.前端代码

html:

<div style="text-align: center;100%;margin:0 auto;margin-top:30px;height:500px;" id="BloodBIChart"></div>

JS: 分段显示 splitNumber

$scope.CalculationDate = function(now, addDays) {
    var nowData = new Date(now);
    nowData = nowData.valueOf();
    nowData = nowData - addDays * 24 * 60 * 60 * 1000;
    nowData = new Date(nowData);
    return nowData.getFullYear() + "-" + (nowData.getMonth() + 1) + "-" + nowData.getDate();
};
$scope.Data = {
    BloodData: { xData: [], yData: [], count: 0, Max: 10, xInterval: 0 }
};

//默认查询最近一个月
var date = new Date();
$scope.EndTime = date.getFullYear() + "-" + (date.getMonth() + 1) + "-" + date.getDate();
$scope.BeginTime = $scope.CalculationDate($scope.EndTime, 30);
        
$scope.Query = function () {
var bloodChart = echarts.init(document.getElementById('BloodBIChart'));
var bloodPressOpt = {
    color: ['#29ccbf'],
    title: {
        text: ''
    },
    tooltip: {
        trigger: 'axis'
    },
    legend: {
        data: ['血压监测人次']
    },
    grid: {
        left: '10%',
        bottom: '35%',
        containLabel: true
    },
    toolbox: {
        feature: {
            //   saveAsImage: {}
        }
    },xAxis: {
        type: 'category',

        axisLabel: {
            interval: 0,
            rotate: 40
        },
        boundaryGap: false,
        splitNumber: 30,
        data: []
    },
    yAxis: {
        type: 'value',
        min: 0,
        splitNumber: 10,
        max: 30
    },
    series: [
        {
            name: '血压监测人次',
            type: 'line',
            data: []
        }
    ]
};
bloodChart.setOption(bloodPressOpt);
bloodChart.showLoading();
res.get({ 'Data.BeginTime': $scope.BeginTime, 'Data.EndTime': $scope.EndTime, 'CurrentPage': 1, 'PageSize': 0 }, function (data) {
    bloodChart.hideLoading();
    $scope.Data.BloodData.xData.length = 0;
    $scope.Data.BloodData.yData.length = 0;
    $scope.Data.BloodData.count = 0;
    $scope.Data.BloodData.xInterval = 0;
    $scope.Data.BloodData.Max = 10;
    if (data.IsSuccess && data.Data) {
        for (var i = data.Data.length - 1; i >= 0; i--) {
            var obj = data.Data[i];
            $scope.Data.BloodData.Max = $scope.Data.BloodData.Max > obj.DaybloodNum ? $scope.Data.BloodData.Max : obj.DaybloodNum;
            $scope.Data.BloodData.xData.push(obj.StartDate.substring(0, 10));
            $scope.Data.BloodData.yData.push(obj.DaybloodNum);
            $scope.Data.BloodData.count += obj.DaybloodNum;
        }

        /*纵轴固定10等分显示,上限取大于最大值的最小10的整数倍,如最大值为11,上限取大于11的10最小10的整数倍为20,10等分每一间隔为2*/
        if (data.Data.length > 30) {
            $scope.Data.BloodData.xInterval = Math.floor(data.Data.length / 30);
        }
    };
    /*
    横轴时间最多显示30个时间点,当时间范围超过30天时,日期间隔显示
     如<=30天,全部日期显示
     30<M<=60,间隔1天显示
     60<M<=90,间隔2天显示
    */
    var bavg = $scope.Data.BloodData.Max % 10;
    $scope.Data.BloodData.Max = bavg == 0 ? $scope.Data.BloodData.Max : ($scope.Data.BloodData.Max + (10 - bavg));

    //血压监测人次
    var bloodPressOption = {
        xAxis: {
            type: 'category',
            axisLabel: {
                interval: $scope.Data.BloodData.xInterval,
                rotate: 40
            },
            boundaryGap: false,
            splitNumber: 30,
            data: $scope.Data.BloodData.xData
        },
        yAxis: {
            type: 'value',
            min: 0,
            splitNumber: 10,
            max: $scope.Data.BloodData.Max
        },
        series: [
            {
                name: '血压监测人次',
                type: 'line',
                data: $scope.Data.BloodData.yData
            }
        ]
    };
    bloodChart.setOption(bloodPressOption);
});
};
View Code

11. angularjs 操作checkbox  参考 http://blog.csdn.net/csdn_lihe/article/details/49782947

 HTML:

<div>  
    <div ng-repeat="color in colors">  
        <input type="checkbox" ng-checked="isChecked(color.id)"   
            ng-click="updateSelection($event,color.id)" />{{color.name}}  
    </div>  
</div>  
<div>  
    Selected : {{selected}}  
</div>  

JS:

psmsApp.controller("vipApplyEditCtrl", function($scope) {  
    $scope.colors = [  
        {id : 1, name : 'black'},  
        {id : 2, name : 'red'},  
        {id : 3, name : 'blue'},  
        {id : 4, name : 'yellow'},  
        {id : 5, name : 'green'},  
        {id : 6, name : 'white'}  
    ] ;  
      
    $scope.selected = [] ;  
      
    $scope.isChecked = function(id){  
        return $scope.selected.indexOf(id) >= 0 ;  
    } ;  
      
    $scope.updateSelection = function($event,id){  
        var checkbox = $event.target ;  
        var checked = checkbox.checked ;  
        if(checked){  
            $scope.selected.push(id) ;  
        }else{  
            var idx = $scope.selected.indexOf(id) ;  
            $scope.selected.splice(idx,1) ;  
        }  
    } ;  
});  

 效果图:

   

 12.angularjs 多选checkbox,C#后台需要定义数组字段

 C# 后台关键代码:

public string[] nameArray { get;set;}  
public string name { get;set;}   

//保存数据
request.name = string.Join(",", nameArray);

//获取数据,返回给前端
response.nameArray = name.Split(',');

HTML:

  <div name="nameArray" ng-model="testInfo.nameArray"  button-type="checkbox"></div>

13. $parse/$eval和$observe/$watch如何区分 http://www.ngnice.com/posts/2314014da4eea8

14.Angularjs 中 copy 赋值与 = 赋值 区别  https://segmentfault.com/q/1010000004183048 

AngularJS:

<!DOCTYPE html>
<html>
<script src= "http://apps.bdimg.com/libs/angular.js/1.3.9/angular.min.js"></script>
<body>
<div ng-app="myApp" ng-controller="formCtrl">
  <form novalidate>
    First Name:<br>
    <input type="text" ng-model="user.firstName"><br>
    Last Name:<br>
    <input type="text" ng-model="user.lastName">
    <br><br>
    <button ng-click="reset()">RESET</button>
  </form>
  <p>form = {{user }}</p>
  <p>master = {{master}}</p>
</div>
<script>
var app = angular.module('myApp', []);
app.controller('formCtrl', function($scope) {
    $scope.master = {firstName:"John", lastName:"Doe"};
    $scope.reset = function() {
        $scope.user = angular.copy($scope.master);
        //$scope.user = $scope.master;
        // 为什么用 $scope.user = $scope.master; master跟着user改变
    };
    $scope.reset();
});
</script>
</body>
</html>

为什么用 $scope.user = $scope.master; $scope.master 会跟着 $scope.user 改变?angular.copy 和 = 号赋值有什么区别呢?

1).内存里有一段地址储存了 { firstName: "John", lastName: "Doe" } 这个数据,并且最开始用 $scope.master 指向了它
当你 $scope.user = $scope.master 的时候,事实上是让二者同时指向了该数据,因此一个变了另外一个也会跟着变
当你 $scope.user = angular.copy($scope.master) 的时候,先做了一份该数据的拷贝(也就是内存中多了另外一份数据,值是一样的,但地址肯定不同),然后让 $scope.user 指向了这份拷贝,所以二者指向了不同的内存地址,当然不会相互影响了。
记住,这并非 Angular 的特殊情况,而是编程语言的通用基础。

2).其实就是一个是拷贝数据,一个是拷贝引用。无论何种编程语言都会有这个问题,所以就会有深拷贝这种概念。

15.angualrjs 循环 

  

    要显示这样的数据。

   HTML:

<table border="1" cellspacing="0" cellpadding="0" class="table-body table-body1" id="tbTest">
</table>

JS:

$scope.testItems = "药物过敏史,手术史,过敏史,腰围,骨密度,骨密度1,骨密度2,骨密度3";
if ($scope.testItems) {
var testItem = $scope.testItems.split(',');
var str = '';
if (testItem != null && testItem.length > 0) {
    angular.forEach(testItem, function (item, index) {
        if ((index + 1) == 1) {
            str += '<tr>';
        }
        str += '<td>' + item + '</td>';
        if ((index + 1) % 3 == 0) {
            str += '</tr>';
        }
    });
    angular.element("#tbTest").append(str);
 }
}

 15.获取AngularJS某个元素的Scope 具体可参考http://www.cnblogs.com/darrenji/archive/2016/02/02/5178456.html

     angular.element($0).scope() 

16.ng-bind 和{{}} 绑定数据,在引入angularjs库的页面建议用ng-bind 来绑定数据,因为用{{}}绑定,会出现{{}}表达式,用户体验不好。

Angularjs 官方API: http://docs.ngnice.com/api/ng 

Angularjs 版本下载:https://code.angularjs.org/

学习博客:http://zhex.me/

17.ng-bind 与ng-model区别

双向绑定,一般来说是这样

<input ng-model="object.xxx">
<span ng-bind="object.xxx"></span>

ng-bind是从$scope -> view的单向绑定,也就是说ng-bind是相当于{{object.xxx}},是用于展示数据的。
ng-modle是$scope <-> view的双向绑定

18.html转义 

app.filter('trustHtml', ['$sce', function ($sce) {
        return function (input) {
            return $sce.trustAsHtml(input);
        }
}]);

  <td ng-bind-html="nurse|trustHtml"></td>

19.如果满足条件,则背景高亮显示。 ng-class="{'normalBackground':ReturnData.Result=='正常'}"

20.通过controller来获取Angular应用 

function AppBack() {
    //通过controller来获取Angular应用
    var appElement = document.querySelector('[ng-controller=testCtrl]');
    //获取$scope变量
    var $scope = angular.element(appElement).scope();
    $scope.goBack();
}

 21.angularjs异步加载之后,定位在滚动条第一个地方。

$timeout(function () {
    $("#modelCont").animate({ scrollTop: $('#'+$scope.trID).offset().top - $("#modelCont").offset().top + $("#modelCont").scrollTop() }, "slow");
}, 10);

 22. MVC,MVP和MVVM

1).MVC模式
M   Model       模型-数据
V   View        视图-表现层        HTML/CSS
C   Controller  控制器-业务逻辑
1.M和V耦合度高
2.C特别臃肿

2).MVP
M
V
P   Presenter   主持人
1.M和V没有耦合
2.P特别特别臃肿

3).MVVM
M
V
VM    ViewModel
1.M和V没有耦合
2.MV还好
MVC   经典
MVP   解除耦合;P臃肿
MVVM  一部分简单逻辑放到HTML里面
  取消臃肿
  直接、粗暴

 23.

1.双向绑定            ng-model
  数据变了<->视图变化
     V   <->   M

  *自动同步数据和视图
2.
ng-model    双向绑定
ng-bind     输出
  单向      数据->视图
ng-app      范围

ng-model    双向绑定
  数据、视图自动同步

ng-bind     单向绑定(输出)
  数据->视图

ng-app      范围

 24. $q.all 的用法

var saveDeseasePromise = function () {
    var deferred = $q.defer();
    deseaseRes.save($scope.Desease, function (result) {
        deferred.resolve();
    });
    return deferred.promise;
}
var saveFamilyPromise = function () {
    var deferred = $q.defer();
    familyRes.save($scope.Family, function (result) {
        deferred.resolve();
    });
    return deferred.promise;
} 
$scope.Save = function () {
    $q.all([saveFamilyPromise(),saveDeseasePromise()]).then(function(value) {
        if ($scope.IsDrugStore) {
            utility.alert("正在保存中...");
        }
    },
    function(value) {
        utility.alert("保存失败...");
    });
}

 25.common.js

let commonMod=angular.module('common', []);
commonMod.config(function ($httpProvider){
  $httpProvider.defaults.transformRequest=function (obj){
    let arr=[];

    for(let name in obj){
      arr.push(`${encodeURIComponent(name)}=${encodeURIComponent(obj[name])}`);
    }

    return arr.join('&');
  };
  $httpProvider.defaults.headers.post['Content-Type']='application/x-www-form-urlencoded';
});

 26.AngularJs 去掉重复的属性值 

$scope.TestList = [];
$scope.TestFilter = {};
for (var item in obj) {
    if (obj.hasOwnProperty(item)) {
        item = item.trim();//去除前后空格
        //判断,不存在重复的属性值 
        if (!$scope.TestFilter[item]) {
            //将属性值添加到对象末尾
            var data = obj[item]; 
              $scope.TestList.push(data);
            }   
            //属性值赋给对象
            $scope.TestFilter[item] = item;
        }
    }
}

 27. ng-options <select>

ng-options="值 as 字 for xxx in arr"

ng-options——替你组织option
1.必须有ng-model
2.值 as 字 for item in arr

group

值 as 字 group by 分类依据 for 名字 in 数组

<!DOCTYPE html>
<html ng-app="test">
  <head>
    <meta charset="utf-8">
    <title></title>
    <script src="angular.js" charset="utf-8"></script>
    <script>
    let mod=angular.module('test', []);

    mod.controller('main', function ($scope){
      $scope.arr=[{id: 1, name: '北京', type: '直辖市'}, {id: 2, name: '上海', type: '直辖市'}, {id: 3, name: '深圳', type: '直辖市'}, {id: 4, name: '武汉', type: '省会'}, {id: 5, name: '津市', type: '湖南省'}, {id: 5, name: '娄底', type: '湖南省'}];
      $scope.city=1;
    });
    </script>
  </head>
  <body ng-controller="main">
    <select ng-model="city" ng-options="item.id as item.name group by item.type for item in arr"></select>
    {{city}}
  </body>
</html>

 28. ng-class-odd 

 29.深拷贝 angular.copy(source, [destination])

angular.copy(data.ReturnData, $scope.TestTypes);
$scope.TestTypes.unshift({ ID: 0, Name: '无', Select: false });//添加到数组的第一项

使用angular的同学可能都忽略了angularJS自带的封装好的方法。angular.isString(), angular.isNumber(),angular.isArray() , angular.isFunction() 等等。其中解决深拷贝的方法angular.copy(),能够解决深拷贝的问题。如下:
var a = {
name :"zhangsan",
age : 20
}
var b = angular.copy(a);
此时,改变b的值,a的值就不会随着b的值的改变而改变,也就解决了深拷贝的问题。

参考:1.https://www.jb51.net/article/109217.htm 

 30. angular的异步处理$q的使用(promise)

31.angular如何分别编译生产环境与开发环境的? 

 Angular 为开发环境提供了 JIT(即时)编译方式,为生产环境提供了 AOT(预先)编译方式。 
34.
            <li ng-repeat="(index,item) in Tabs"  
              ng-click="switchTabs(index)" 
              ng-class="index === tabsIndex ? 'active' : ''">{{item}}</li>

              <!-- 或者这样写 <li ng-repeat="item in Tabs track by $index"  
              ng-click="switchTabs($index)" 
              ng-class="$index === tabsIndex ? 'active' : ''">{{item}}</li> -->
 
       //当页面加载完
    //    scope.$on('$viewContentLoaded',()=>{
 
    //    });
setTimeout(()=>{
                 
                   },100);
 
原文地址:https://www.cnblogs.com/allenhua/p/7560057.html