在角度js ng-repeat之后重新绑定jquery

时间:2012-11-24 17:45:01

标签: javascript jquery angularjs binding angularjs-ng-repeat

我正在使用$http.get()服务在angularJS中填写一个数组,通过调用rest api。使用ng-repeat显示此数组。有一个Jquery代码可以在每个<li>标签上悬停时显示一个按钮。 $http导致获取数据的延迟,此时Jquery将完成绑定。所以悬停功能不起作用。有没有解决这个问题?

<!doctype html>
<html ng-app>
<head>
<meta charset="utf-8">
<title>Untitled Document</title>
<script src="angular.js"></script>
<script src="jquery.js"></script>
<script>
$(document).ready(function() {
    myFunction();
});
var myFunction= function(){
$("#orders ul li").hover(
        function() {
            $(this ).find(".butt-view").show();
        },
        function() {
            $(this ).find(".butt-view").hide();
        });
}
</script>
<script>
function PhoneListCtrl($scope) {
    $scope.phones = $http.get(url);
}
</script>
<style>
ul{list-style-type:none;}
ul li{background-color:#e1eff2; padding:5px 6px;}
ul li:hover{background-color:#fff;}
.butt-view{background-color:#feb801; border-radius:4px; color:#fff; font: bold 12px Arial, Helvetica, Sans-serif; padding:5px 7px; margin-top:3px; width:40px }
</style>
</head>
<body ng-controller="PhoneListCtrl">
<div id="orders">
<ul>
<li ng-repeat="phone in phones" >
  {{phone.name}}
  <p>{{phone.snippet}}</p>
  <p class="butt-view">View</p>
</li>
</ul>
</div>
</body>
</html>

3 个答案:

答案 0 :(得分:17)

虽然jQuery方法可能正常工作,但这并不是AngularJS解决问题的方法。

AngularJS推广以声明方式表达的UI(换句话说,我们确实描述了期望的效果,而不是指示为实现效果而采取的每个小步骤)。 使用指令我们可以告诉AngularJS我们希望UI在响应模型突变时的样子。因此,使用AngularJS,我们更专注于在模板中声明性地描述UI,然后通过模型突变来驱动此UI 。 AngularJS将完成剩余的重举。

这一切可能听起来有点神秘,所以这里的问题解决了AngularJS的方式(模型不会改变,只有模板会这样做):

<ul>
<li ng-repeat="phone in phones" ng-mouseenter="showView=true" ng-mouseleave="showView=false">
  {{phone.name}}
  <p>{{phone.snippet}}</p>
  <p class="butt-view" ng-show="showView">View</p>
</li>
</ul>

请注意,这是所有使其工作所需的内容:无需对DOM元素进行adid,也无需编写任何 JavaScript代码。 它允许我们删除14行JavaScript代码并完全删除对jQuery的依赖。很好,不是吗?

最后,这是一个有效的jsFiddle:http://jsfiddle.net/GBwLN/4/

答案 1 :(得分:6)

使用event delegation,这是新的.on() jQuery方法引入的更好的方法,只需替换以下代码:

$("#orders ul li").hover(
        function() {
            $(this ).find(".butt-view").show();
        },
        function() {
            $(this ).find(".butt-view").hide();
        });

这个:

$("#orders").on('mouseenter mouseleave', 'li', function(event) {
     if (event.type == 'mouseenter') {
         $(this ).find(".butt-view").show();
     } else  {
         $(this ).find(".butt-view").hide();
     }
});

通过这种方式,您可以将事件处理程序附加到#orders div,而不是单独的li元素,当li元素悬停时,事件将会冒出来直到获取#orders上的处理程序。这种方法更有效,并且可用于dinamycally添加新的li。

顺便说一句,我使用的mouseenter mouseleave事件相当于hover,并且在我看来更具可读性。

答案 2 :(得分:1)

您应该使用事件委派,但您也可以使用指令实现此目的:

HTML:

<li ng-repeat="phone in phones" awesome-item>
  {{phone.name}}
  <p>{{phone.snippet}}</p>
  <p class="butt-view">View</p>
</li>

指令:

angular.module('darthvader', [])
  .directive('awesomeItem', function() {
    return function($scope, element, attrs) {
        element.hover(function() {
            $(this).find(".butt-view").show();
        },
        function() {
            $(this).find(".butt-view").hide();
        });
    };
  });