在使用angularjs时遇到的几个问题

1、$http.post发的数据,后台取不到

      我用的是springMVC框架,前端提交数据使用了$http.post(url, data)方法,不知道为什么总是取不到data数据。如果直接用$.post(url, data); 就可以!

           $http.post('spring/mvc', {
                user: userForm,
                test: 'test'
            }).success(function(){
                alert("保存成功");
            });

     后台的一个controller:


@RequestMapping(value = "/mvc", method = RequestMethod.POST)
     @ResponseBody
public
void setMenu(User user, String test) {
              System.out.println("user= " + user.toString());
System.out.println("test = " + test); }

      打印出来,始终是null.如果直接用$.post就可以正常打印出: test

          $.post('spring/mvc', {
            user: userForm,
            test: 'test'
        });

      针对以上问题的最终解决方案是:

          var url = 'spring/mvc',
            data = {
             #  user: JSON.stringify(userForm),
                user: angular.toJson(userForm),   #此处使用angular.toJson方法的原因在下面说明
  test: 'test test'
 
},
 transFn = function(data) {
return $.param(data);
},
 postCfg
= {
headers
: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},
 transformRequest
: transFn
 
};
$http
.post(url, data, postCfg)
.
success(function(){
alert("成功")
;
});

2、scope中的数据明明改变了但是为什么页面却没有更新?

       这种问题可能是由于没有进入AngularJS自己的Context中去而引起无法对视图进行更新导致的,这个时候你可能要手动进行更新

       你可以尝试使用$apply或者$digest,但也不要过度滥用$digest,毕竟每次调用都是要消耗很多的资源的,但有时候调用了会遇到如下的报错:

4ba20dc82d4d396806f46dfd854969f5.jpg

        遇到这种问题一般是由于在手动调用$digest的时候使用不当造成的,使用如下的封装就可以了

       
  
  
var  updateUI =  function (){
     if (!$scope.$$phase){
      $scope.$digest();
     }
};
var  updateRootUI =  function (){
     if (!$rootScope.$$phase){
      $rootScope.$digest();
     }
};

3、提交的数据多了会出现很多$$hashKey怎么办

         比如下面的数据

f708395a5ae57bf533766720e82259ff.jpg

           这个是因为$$hashKey是AngularJS为了做DirtyCheck加的haskKey,解决这个办法也很简单,在做序列化处理的时候使用angular.toJson函数

           代替JSON.stringify来序列化数据即可,这也是一个问题中为什么将JSON.stringify注掉使用angular.toJson的原因。


     解决该问题除了使用angular.toJson函数来序列化以外还可以自己在 ng-repeat 的时候写上 track by也可以避免出现$$hashKey。

          比如 track by $index    或  

     <div ng-controller="Test">
       <button ng-click="request()">请求新数据</button>
          // 使用 track by 标识
       <div ng-repeat="user in users track by user.id">
          {{user.name}}
       </div>
    </div>
     以上两种方式均可避免出现 $$hashKey,具体为什么会出现这种问题呢?

    在查看 ng-repeat 的源码时可以发现,当 ng-repeat 的数组被替换时, 它默认并不会重新利用已有的 Dom 元素,而是直接将其全部删除并重新生成新的数组 Dom 元素:

     // 将上次生成的所有 dom 移除
     for (key in lastBlockMap) {
       if (lastBlockMap.hasOwnProperty(key)) {
         block = lastBlockMap[key];
         elementsToRemove = getBlockElements(block.clone);
         $animate.leave(elementsToRemove);
         forEach(elementsToRemove, function(element) { element[NG_REMOVED] = true; });
         block.scope.$destroy();
       }
     }

    Dom 的频繁操作是非常不友好的,为什么 ng-repeat 不能利用已有的 dom 元素去更新数据呢?因为你没有把数组元素的标识属性告诉它,

    那么两次替换的时候它就没办法追 踪了,我们可以看到 ng-repeat 往数组里每个元素加了一个 $$hashKey 的属性:

      

      这个 key 是由 Angular 内部的 nextUid() 方法生成的,类似数据库自增,但是使用的是字符串。

     现在我们明白了,因为每次替换数组都会导致 ng-repeat 为每个元素生成一个新 key, 所以根本没办法重用已有的 Dom 元素,那么我们可以使用下边的语法来避免这个问题:

   <div ng-controller="Test">
    <button ng-click="request()">请求新数据</button>
     // 使用 track by 标识
     <div ng-repeat="user in users track by user.id">
        {{user.name}}
     </div>
   </div>

这样 ng-repeat 就会将其缓存起来啦,当然可能你的数组元素没有一个标识属性,如果元素数量不多那么可以接受,不然还是建议你手动为其生成一个标识属性。


4、页面加载为什么会有那么多404?

     这个一般是由于模板里面直接使用了src,请使用ng-src替代src,这里提一下,sodaRender里请使用soda-src

        <img ng-src="{{user.name}}" />


5、多层循环嵌套时$index重复的问题

         这个跟第三条中提到的是一样的,使用track by 语法(sodaRender也支持)就可以了

          <li ng-repeat="user in users track by $subindex"></li>


6、自己封装的Directive,如何像ng-model一样好用

      这里可以使用directive中的require配置项,将ng-model Directive引进来,并在合适的时间调用setViewValue方法,如下:

QQ截图20151201110605.jpg

7、ng-model想使用个性化问题

       有些时候,ng-model并不能满足所有的场景需求,这个时候可以考虑使用set、get方法做一层拦截,这样就可以更好的控制数据绑定,如下

QQ截图20151201110640.jpg

         然而在1.3+的版本中,angularJS似乎也意识到了ng-model的这一点,所以它开放了API允许我们进行拦截

QQ截图20151201110714.jpg

QQ截图20151201110730.jpg

          只不过,AngularJS讲set和get方法合二为一,这一点也是比较巧妙的。


以上这些问题汇总仅供有需要的同学参考,如有更好的解决方法欢迎在下面留言,共同学习、交流


  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用AngularJS制作一个购物车需要以下步骤: 1. 定义一个AngularJS app模块和controller控制器。 ```javascript var app = angular.module('myApp', []); app.controller('myCtrl', function($scope) { // 初始化购物车为空数组 $scope.cart = []; }); ``` 2. 在HTML中定义购物车的容器,并使用ng-repeat指令遍历购物车中的商品列表。 ```html <div ng-app="myApp" ng-controller="myCtrl"> <div ng-repeat="item in cart"> <div>{{item.name}}</div> <div>{{item.price}}</div> <div>{{item.quantity}}</div> <div>{{item.price * item.quantity}}</div> </div> </div> ``` 3. 在HTML中定义商品列表,并为每个商品添加一个“添加到购物车”的按钮。当用户点击按钮,将该商品添加到购物车中。 ```html <div ng-app="myApp" ng-controller="myCtrl"> <div ng-repeat="product in products"> <div>{{product.name}}</div> <div>{{product.price}}</div> <button ng-click="addToCart(product)">添加到购物车</button> </div> <hr> <div ng-repeat="item in cart"> <div>{{item.name}}</div> <div>{{item.price}}</div> <div>{{item.quantity}}</div> <div>{{item.price * item.quantity}}</div> </div> </div> ``` 4. 在controller中实现addToCart()函数,用于将商品添加到购物车中。 ```javascript $scope.addToCart = function(product) { // 检查购物车中是否已存在该商品 var index = -1; for (var i = 0; i < $scope.cart.length; i++) { if ($scope.cart[i].name === product.name) { index = i; break; } } // 如果购物车中已存在该商品,则将商品数量加1 if (index !== -1) { $scope.cart[index].quantity++; } else { // 否则将商品添加到购物车中 $scope.cart.push({ name: product.name, price: product.price, quantity: 1 }); } }; ``` 这样就可以实现一个简单的购物车了。当然,你可以根据实际需求对代码进行修改和优化。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值