3

$http.get()通过调用rest api使用服务填充angularJS中的数组。该数组使用 显示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>
4

3 回答 3

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 元素添加 id,也无需编写任何JavaScript 代码。它允许我们删除 14 行 JavaScript 代码并完全删除对 j​​Query 的依赖。甜,不是吗?

最后这里是一个工作 jsFiddle:http: //jsfiddle.net/GBwLN/4/

于 2012-11-24T20:28:15.660 回答
6

使用事件委托,这是新.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();
     }
});

这样,您将事件处理程序附加到您的#ordersdiv,而不是单个li元素,当一个li元素悬停时,事件将冒泡直到到达您的处理程序#orders。这种方法更有效,适用于动态添加的新 li。

顺便说一句,我使用的 mouseenter mouseleave事件等同hover于我认为更具可读性的事件。

于 2012-11-24T17:48:35.363 回答
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();
        });
    };
  });
于 2014-10-15T20:27:58.710 回答