前言
大家都知道 angualrjs 处于安全的考虑,插值 指令会对相应字符串进行过滤,避免出现 html 攻击。但是在一些时候,我们需要渲染 html,比如实现一个分级的下拉框
代码如下:
- <body ng-app="app" ng-controller="controller">
- <select ng-model="value" ng-options="t.text for t in testList">
- </select>
- <script src="/bootstrap/bootstrap/dist/angular-bootstrap/angular.js">
- </script>
- <script type="text/javascript">
- var app = angular.module("app", []);
- app.controller("controller", ["$scope",
- function($scope) {
- var testList = [{
- id: 0,
- text: " 全国"
- },
- {
- id: 1,
- text: " 北京"
- },
- {
- id: 20,
- text: " 上海"
- },
- {
- id: 3,
- text: " 福建"
- },
- {
- id: 4,
- text: " 山东"
- }];
- $scope.value = 20;
- $scope.testList = testList;
- }]);
- </script>
- </body>
可以看到,空格直接被渲染为
。一个简单粗暴的解决办法是修改 angularjs 源代码,不再对 html 进行过滤,在 angularjs 源码中搜索
函数,直接对相应脚本进行替换,如下图:
- updateOptions
可以看到,空格已经被正确的渲染,这种方式虽然简单,但是修改将会影响到所有的下拉框控件,有可能会受到 html 攻击,一种比较中规中矩的办法是采用
来渲染 html,这个时候下拉框绑定数据的方式也需要改变,相应代码如下:
- ng-bind-html
- <body ng-app="app" ng-controller="controller">
- <select ng-module="value">
- <option ng-repeat="data in testList" value="{{data.id}}" ng-selected="data.id==value"
- ng-bind-html="data.text">
- </option>
- </select>
- <script src="/bootstrap/bootstrap/dist/angular-bootstrap/angular.js">
- </script>
- <script type="text/javascript">
- var app = angular.module("app", []);
- app.controller("controller", ["$scope", "$sce",
- function($scope, $sce) {
- var testList = [{
- id: 0,
- text: " 全国"
- },
- {
- id: 1,
- text: " 北京"
- },
- {
- id: 20,
- text: " 上海"
- },
- {
- id: 3,
- text: " 福建"
- },
- {
- id: 4,
- text: " 山东"
- }];
- for (var i = 0; i < testList.length; i++) {
- testList[i].text = $sce.trustAsHtml(testList[i].text);
- }
- $scope.value = '20'; //注意,此处必须为字符串类型,否则无法获取选中的值
- $scope.testList = testList;
- }]);
- </script>
- </body>
这种方式非常消耗性能,对于数据量不大的下拉框,这种方式完全可以满足需要,但是如果数据量稍微大些,浏览器就会出现明显的卡顿现象,这个时候可以自己写一个指令来实现下拉框,代码如下:
- <body ng-app="app" ng-controller="controller">
- <drop-down-list d-list="testList" value="id" text="text" d-select-value="value">
- </drop-down-list>
- {{value}}
- <script src="/bootstrap/bootstrap/dist/angular-bootstrap/angular.js">
- </script>
- <script type="text/javascript">
- var app = angular.module("app", []);
- app.controller("controller", ["$scope", "$window",
- function($scope, $window) {
- var testList = [{
- id: 0,
- text: " 全国"
- },
- {
- id: 1,
- text: " 北京"
- },
- {
- id: 20,
- text: " 上海"
- },
- {
- id: 3,
- text: " 福建"
- },
- {
- id: 4,
- text: " 山东"
- }];
- $scope.value = 20;
- $scope.testList = testList;
- }]);
- app.directive("dropDownList",
- function() {
- return {
- restrict: 'E',
- scope: {
- dList: '=',
- dSelectValue: '='
- },
- link: function(scope, element, attrs) {
- var d = document;
- var value = attrs["value"]; //对应option的value
- var text = attrs["text"];
- var selectValue = scope.dSelectValue;
- element.on("change",
- function() {
- var selectedIndex = this.selectedIndex;
- scope.$apply(function() {
- scope.dSelectValue = selectedIndex;
- });
- })
- for (var i = 0; i < scope.dList.length; i++) {
- var option = d.createElement("option");
- option.value = scope.dList[i][value];
- option.innerHTML = scope.dList[i][text];
- if (selectValue == option.value) {
- option.setAttribute("selected", true);
- }
- element.append(option);
- }
- },
- template: '<select></select>',
- replace: true
- };
- });
- </script>
- </body>
这种方式可以比较完美的实现相应功能,是一种较好的选择。
总结
来源: http://www.jb51.net/article/116499.htm