zoukankan      html  css  js  c++  java
  • 前端遇到的一些坑

    1、 angular强制清除浏览器缓存

     原文是这样记录的:

    Caching

    $http responses are not cached by default. To enable caching, you must set the config.cache value or the default cache value to TRUE or to a cache object (created with $cacheFactory). If defined, the value of config.cache takes precedence over the default cache value.

    In order to:

    • cache all responses - set the default cache value to TRUE or to a cache object
    • cache a specific response - set config.cache value to TRUE or to a cache object

    If caching is enabled, but neither the default cache nor config.cache are set to a cache object, then the default $cacheFactory("$http")object is used.

    The default cache value can be set by updating the $http.defaults.cache property or the $httpProvider.defaults.cache property.

    When caching is enabled, $http stores the response from the server using the relevant cache object. The next time the same request is made, the response is returned from the cache without sending a request to the server.

    Take note that:

    • Only GET and JSONP requests are cached.
    • The cache key is the request URL including search parameters; headers are not considered.
    • Cached responses are returned asynchronously, in the same way as responses from the server.
    • If multiple identical requests are made using the same cache, which is not yet populated, one request will be made to the server and remaining requests will return the same response.
    • A cache-control header on the response does not affect if or how responses are cached.

    翻译:

    缓存

    $http响应默认不是缓存的。为了能够缓存,必须设置config.cache的值,或者默认的cache值为TRUE,或者创建缓存对象(由$cacheFactory创建)。如果定义了,配置的cache值比默认的cache值优先级高。

    为了:

    • 缓存所有响应 - 设置缓存值为TRUE或者设置缓存对象
    • 缓存指定响应 - 设置config.cache的值为TRUE或者设置缓存对象

    如果缓存生效,但是既没有设置默认cache,也没有设置config.cache为缓存对象,那么默认的 $cacheFactory("$http")将会使用。

    默认的cache值可以通过更新$http.defaults.cache属性或 $httpProvider.defaults.cache属性来设置

    当缓存生效时, $http通过使用相关缓存对象,存储来自服务器的响应。如果下一次执行了同样的请求,响应是来自缓存,而不是发送一个请求至服务端。

    注意:

    • 只有GET和JSONP请求有缓存
    • 缓存的key是请求的URL,包含搜索参数,不包含头部
    • 缓存响应是通过异步返回的,与通过服务端响应的方式是一样的。
    • 如果执行多个同样的请求,使用同样的缓存,缓存不是一直存在的,一个请求发送到服务端,剩下的请求返回同样的响应。
    • 响应头的cache-control不会影响是否换存和如何缓存的

    2、记录路由切换时,记录路由的变化

    通过angularjs自带的$locationChangeStart

      .run(['$rootScope', '$window', '$location', '$log', function ($rootScope, $window, $location, $log) {
        var locationChangeStartOff = $rootScope.$on('$locationChangeStart', function(event , next, current) {
          $log.log('locationChangeStart');
          $log.log(arguments);
        });
    
      }])  

    如果请求的参数放在angular自带的params中,并不能很好滴获取页面的请求参数,所以上面的这种解决方案并不是很有效。

    只能另想其法了。

    因为页面的请求URL变化,是通过点击来触发的,可以在触发URL状态变化后,记录状态变化的请求URL,并将请求的URL放在sessionStorage中。

    比如:

    //切换待办已办已建
        $scope.changeTable=function(code){
          $scope.nowCode=code;
          $scope.getOrderDate(pNum,pSize,$scope.nowCode,$scope.status,$scope.searchInfo,$scope.whichOrder);
          //获取当前请求的URL,并保存至sessionStorage中
          sessionStorage.setItem('orderUrl', JSON.stringify({
            url:$location.absUrl(),
            pageNum:pNum,
            pageSize:pSize,
            code:code,
            type:$scope.status,
            keyWord:$scope.searchInfo,
            orderBy:$scope.whichOrder}));
          $rootScope.orderAbsUrl = JSON.parse(sessionStorage.getItem('orderUrl'));
          console.log($rootScope.orderAbsUrl);
        };
    

    下载相应的stateEvent.js文件,就可以解决相应的问题。

     3、ng-click获取当前点击对象,获取自定义属性值

    <span class="operate">
    <i class="iconfont icon-beifen_download" data-value="Windows Server 2008 R2" ng-click="downLoad($event.target)" title="下载"></i>
    </span>
    $scope.downLoad = function (evt) {
          var fileName = $(evt).data('value');
          console.log(fileName);
        };/  

    4、bootstrap模态框清除缓存

    bootstrap 模态框清除缓存,一直不知道如何解决问题,

    网上常见的解决方案是:

         $('body').on('hidden.bs.modal', '.modal', function () {
            $(this).removeData('bs.modal');
          });  

    但是对于的情况不太有效

    <div class="modal allocateModel" tabindex="-1" role="dialog" id="userSysAllocate">
        <div class="modal-dialog allocateDialog" role="document">
            <div class="modal-content allocateContent">
                <div class="modal-header allocateHeader">
                    <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span></button>
                    <h4 class="modal-title">分配备份系统</h4>
                </div>
                <div class="modal-body allocateBody" id="allocateContent">
                    <span class="selectHeader">请选择一个或多个备份系统</span>
                    <div class="selectBtn">
                        <div class="forSelect">
                            <input type="checkbox" ng-model="allSelected" ng-checked="allSelected" class="checkIpt" ng-click="selectAll()" value="全选"><span class="selectEle">全选</span>
                        </div>
                        <ul>
                            <li class="roleSelect" ng-repeat="rUser in rUsers track by $index" style="float: left;">
                                <input type="checkbox" ng-disabled="rUser.creatorId == userBackupId" ng-checked="rUser.relativeState" ng-model="rUser.relativeState" name="chosed" ng-click="allChoose()" class="allCheck checkIptOne" value="{{rUser.systemPkId}}"><span class="selectEle slectRht">{{rUser.systemName}}</span>
                            </li>
                        </ul>
                    </div>
                </div>
                <div class="modal-footer allocateFooter">
                    <button type="button" class="btn btn-default allocateCancle" data-dismiss="modal">取 消</button>
                    <button type="button" class="btn btn-primary allocateConfirm" ng-click="allocateSubmit(userBackupId)">确 定</button>
                </div>
            </div>
        </div>
    </div>

    对应的全选和反选操作是通过原生的Dom操作来实现的,但除了全选的input选择框,剩下都是通过ng-repeat后台获取的,这种是采用的angular方式,也就是angular和原生的Dom操作混用,刚开始还觉得没有问题,后发现全选和反选后,点击取消,再次打开模态框,勾选的没有取消。这就是混用导致的问题。

    所以解决方案就是要么就全部使用原生的dom操作,要么就全部使用angular方式。避免混用出现的不可预测的问题。

    下面是开始的解决方案,也是出现问题的

          $scope.selectAll = function () {
            var objSelect = document.getElementsByClassName('allCheck'),
              len = objSelect.length;
            if($scope.allSelected) {
              for(var i=0; i<len; i++) {
                objSelect[i].checked = true;
              }
            } else {
              for(var i=0; i<len; i++) {
                objSelect[i].checked = false;
              }
            }
          };
          $scope.allChoose = function () {
            var objChoose = document.getElementsByName('chosed'),
              objTrue = [],
              len = objChoose.length;
            for(var i=0; i<len; i++) {
              objTrue.push(objChoose[i].checked);
            }
            var checkRes = objTrue.every(function(item){ return item == true });
            $scope.allSelected = checkRes == true ? true : false;
          };  

    采用纯angular方式  

            $scope.selectAll = function () {
                var len = $scope.rUsers ? $scope.rUsers.length : 0;
                if($scope.allSelected) {
                    for(var i=0; i<len; i++) {
                      $scope.rUsers[i].relativeState = true;
                    }
                } else {
                    for(var i=0; i<len; i++) {
                      $scope.rUsers[i].relativeState = false;
                    }
                }
            };
            $scope.allChoose = function () {
              var len = $scope.rUsers ? $scope.rUsers.length : 0,
                objTrue = [];
              for(var i=0; i<len; i++) {
                  objTrue.push($scope.rUsers[i].relativeState);
              }
              var checkRes = objTrue.every(function(item){ return item == true });
              $scope.allSelected = checkRes == true ? true : false;
            };
    
            $('body').on('hidden.bs.modal', '.modal', function () {
              $(this).removeData('bs.modal');
              $scope.sysPrivilege = [];
              $scope.allSelected = false;
            });
    

    5、使用splice删除数组中符合条件的项

    删除符合条件的项,使用splice来删除,采用倒序的方式,不用break。

    如:

    var str = ['sidebar.roleList{"#":null','sidebar.modifyPassword{"#":null','sidebar.modifyPassword{"#":null'];

    for(var i=str.length;i--;){
    if(str[i].indexOf('sidebar.modifyPassword') != -1){
    str.splice(i,1);
    }

    }
    console.log(str); 

    结果见上。

    6、AngularJS下$http上传文件(AngularJS file upload/post file)

    angularjs上传多个文件,按照网上提示的设置headers: {Content-Type': undefined}和transformRequest: angular.identity,但是仍然提示失败,后来又寻找到另外的一种解决方案:

    $http({
    
      method:'POST',
      url: 'url',
      headers: { 'Content-Type': undefined },
      data: data,
      transformRequest: (data, headersGetter) => {
        let formData = new FormData();
        angular.forEach(data, function (value, key) {
          formData.append(key, value);
        });
        return formData;
       }
    })
    .then(function(response, header, config, status) {
       handle(response, resovle, reject);
     }, function(response, header, config, status) {
         reject('接口访问异常');
    });
    

     不支持箭头函数,仍然提示上传附件失败,改成下面的格式就可以了。不知道是什么原因。

        function uploadFile(url, data) {
          return $q(function(resovle, reject) {
            $http({
              url: url,
              method: 'POST',
              data: data,
              headers: {'Content-Type': undefined},
              transformRequest: function (data, headersGetter) {
                var formData = new FormData();
                angular.forEach(data, function (value, key) {
                  formData.append(key, value);
                });
                return formData;
              }
            }).then(function(response, header, config, status) {
              handle(response, resovle, reject);
            }, function(response, header, config, status) {
              reject('接口访问异常');
            })
          })
        }
    

    7、点击空白区域或非目标区域,关闭气泡,或弹出模态框

    下面是jQuery写法

    $(document).mouseup(function(e){
      var _con = $(' 目标区域 ');   // 设置目标区域
      if(!_con.is(e.target) && _con.has(e.target).length === 0){ // Mark 1
        some code...   // 功能代码
      }
    });
    /* Mark 1 的原理:
    判断点击事件发生在区域外的条件是:
    1. 点击事件的对象不是目标区域本身
    2. 事件对象同时也不是目标区域的子元素
    */  

      

    对于angularjs而言,需要注入$document

    $document.mouseup(function(e){
          var _con = angular.element(".notice-operate");   // 设置目标区域
          if(!_con.is(e.target) && _con.has(e.target).length === 0){ // Mark 1
            $scope.close_popups(); // 功能代码
          }
        });
    

    8、$stateParams获取不到值,返回undefined。

    找了好久,不知原因所在,后来在在网上查到依赖注入输入不一致导致,修改成一致,问题解决了,代码还是要规范。

    angular.module('frontierApp.userManage', ['ui.router', 'frontierApp.pagination', 'angular-popups'])
      .config(['$stateProvider', userConfig])
      .controller('UserListCtrl', ['UserManageService', '$rootScope', '$state','$scope', '$stateParams', '$document', 'BASE_URL', UserListCtrl])
      .controller('UserDetailCtrl', ['UserManageService', '$rootScope', '$state','$scope', '$http', '$stateParams', UserDetailCtrl])
      .controller('UserEditCtrl', ['UserManageService', '$rootScope','$state','$scope', '$http', '$stateParams', UserEditCtrl])
      .controller('UserCreateCtrl', ['UserManageService', '$rootScope','$state','$scope', '$stateParams', UserCreateCtrl]);
    
    function UserDetailCtrl(UserManageService, $rootScope, $state, $scope, $stateParams) {
    /*代码*/
    }  

     

    改成如下

    angular.module('frontierApp.userManage', ['ui.router', 'frontierApp.pagination', 'angular-popups'])
      .config(['$stateProvider', userConfig])
      .controller('UserListCtrl', ['UserManageService', '$rootScope', '$state','$scope', '$stateParams', '$document', 'BASE_URL', UserListCtrl])
      .controller('UserDetailCtrl', ['UserManageService', '$rootScope', '$state','$scope','$stateParams', UserDetailCtrl])
      .controller('UserEditCtrl', ['UserManageService', '$rootScope','$state','$scope','$stateParams', UserEditCtrl])
      .controller('UserCreateCtrl', ['UserManageService', '$rootScope','$state','$scope', '$stateParams', UserCreateCtrl]);
    
    function UserDetailCtrl(UserManageService, $rootScope, $state, $scope, $stateParams) {
    /*代码*/
    }  
    

      

    9,IE10浏览器导出,报400错误。

    查了下,http请求报400错误的原因:

    1)前端提交数据的字段名称或者是字段类型和后台的实体类不一致,导致无法封装;

    2)前端提交的到后台的数据应该是json字符串类型,而前端没有将对象转化为字符串类型;

    导出代码

    location.href = BASE_URL + '/user/userinfos/xls?idOrName='+ keyword;  

      

    解决方法:

    var keyword = $scope.serkey ? $scope.serkey : "";
    var data = {idOrName : encodeURI(keyword)};
    location.href = BASE_URL + '/user/userinfos/xls' + "?" + jsonToUrlStr(data);  

     

    其中jsonToUrlStr函数见下:

        function jsonToUrlStr(data) {
          var strArr = [];
          for (var m in data) {
            strArr.push(m + '=' + data[m]);
          }
          return strArr.join('&');
        }
    

      

      

      

    未完待续。。。  

  • 相关阅读:
    Java8 Stream Function
    PLINQ (C#/.Net 4.5.1) vs Stream (JDK/Java 8) Performance
    罗素 尊重 《事实》
    小品 《研发的一天》
    Java8 λ表达式 stream group by max then Option then PlainObject
    这人好像一条狗啊。什么是共识?
    TOGAF TheOpenGroup引领开发厂商中立的开放技术标准和认证
    OpenMP vs. MPI
    BPMN2 online draw tools 在线作图工具
    DecisionCamp 2019, Decision Manager, AI, and the Future
  • 原文地址:https://www.cnblogs.com/WaTa/p/7474352.html
Copyright © 2011-2022 走看看