许多以 jquery 为中心的 Dom 工作在指令 link 函数中进行 - 这是错误的吗?
Lots of jquery-centric Dom work going on in directives link function - is this wrong?
我正在编写我的第一个指令 - 一个简单的弹出窗口,它在鼠标悬停(或触摸)时显示一些内容。看来我的 link 函数基本上是一些功能的包装器,否则我只是插入 jquery 世界中的一个函数。这是否正确 - 想知道是否有更以 angular 为中心的方法来实现这一点?
http://jsfiddle.net/wx8ydotr/4/
core.directive('popover', ['isTouchDevice', function (isMobileDevice) {
return {
restrict: 'A',
link: function (scope, el, attrs) {
el.addClass("popover");
if (isMobileDevice) {
el.bind("touchstart", function (e) {
show();
});
} else {
el.bind("mouseover", function (e) {
show();
});
el.bind("mouseout", function (e) {
hide();
});
}
function show() {
el.find('div').addClass('show');
}
function hide() {
el.find('div').removeClass('show');
}
}
};
}]);
我的两分钱,我建议让你的 html 更明确。尝试将您的视图表示为模型并在 link 函数中初始化您的模型。
例如,请考虑以下 HTML 片段
<div ng-class="{ 'fade-in': showResults, 'fade-out': !showResults }"></div>
showResults 变量绑定到可在指令的 link 函数中访问的 $scope。根据条件,您可能想要设置 -
$scope.showResults = true/false;
在您的 link 函数中。这样做会使您的视图更具声明性,而不是在 DOM 上操作,您将 DOM 表示为视图模型并在视图模型上操作。
希望这对您有所帮助。
在使用 Angular 时,您应该尽量忘记 jQuery。您可以按照@swazza85 的建议使用 ng-class
,而不是像您那样添加 类,或者简单地使用 ready-made 指令 ng-show
、ng-hide
、ng-mouseover
或 ng-touch
.
实现您现在所拥有的最快最简单的方法是
<div ng-mouseover="show = true" ng-mouseleave="show = false">Some text</div>
<div ng-show="show">Initially hidden</div>
不幸的是,没有指令捕获 touchstart
事件,但您可以通过将这些事件绑定到指令的 link
函数中来解决这个问题,正如您已经完成的那样。
一种更 angular 编写您的意图的方法,包装为指令,可能是以下内容。
HTML 模板
<body ng-controller="Ctrl as vm">
<pop content="vm.val1" hover="vm.val2"></pop>
</body>
JavaScript
app.controller('Ctrl', function() {
this.val1 = 'Touch or move mouse over the label';
this.val2 = '...I haz appeared!!1';
});
app.directive('pop', function() {
return {
restrict: 'E',
scope: {
content: '=',
hover: '='
},
template: '<div ng-mouseover="toggle(true)" ng-mouseleave="toggle(false)">' +
' <h4><span class="label label-default">{{ content }}</span></h4>' +
'</div>' +
'<div ng-show="show" class="alert alert-info">{{ hover }}</div>',
link: function(scope, element) {
scope.toggle = function(val) {
scope.show = val;
};
element.bind('touchstart', toggle, true);
element.bind('touchend', toggle, false);
}
};
});
相关插件在这里http://plnkr.co/edit/JjydPL
我正在编写我的第一个指令 - 一个简单的弹出窗口,它在鼠标悬停(或触摸)时显示一些内容。看来我的 link 函数基本上是一些功能的包装器,否则我只是插入 jquery 世界中的一个函数。这是否正确 - 想知道是否有更以 angular 为中心的方法来实现这一点?
http://jsfiddle.net/wx8ydotr/4/
core.directive('popover', ['isTouchDevice', function (isMobileDevice) {
return {
restrict: 'A',
link: function (scope, el, attrs) {
el.addClass("popover");
if (isMobileDevice) {
el.bind("touchstart", function (e) {
show();
});
} else {
el.bind("mouseover", function (e) {
show();
});
el.bind("mouseout", function (e) {
hide();
});
}
function show() {
el.find('div').addClass('show');
}
function hide() {
el.find('div').removeClass('show');
}
}
};
}]);
我的两分钱,我建议让你的 html 更明确。尝试将您的视图表示为模型并在 link 函数中初始化您的模型。
例如,请考虑以下 HTML 片段
<div ng-class="{ 'fade-in': showResults, 'fade-out': !showResults }"></div>
showResults 变量绑定到可在指令的 link 函数中访问的 $scope。根据条件,您可能想要设置 -
$scope.showResults = true/false;
在您的 link 函数中。这样做会使您的视图更具声明性,而不是在 DOM 上操作,您将 DOM 表示为视图模型并在视图模型上操作。
希望这对您有所帮助。
在使用 Angular 时,您应该尽量忘记 jQuery。您可以按照@swazza85 的建议使用 ng-class
,而不是像您那样添加 类,或者简单地使用 ready-made 指令 ng-show
、ng-hide
、ng-mouseover
或 ng-touch
.
实现您现在所拥有的最快最简单的方法是
<div ng-mouseover="show = true" ng-mouseleave="show = false">Some text</div>
<div ng-show="show">Initially hidden</div>
不幸的是,没有指令捕获 touchstart
事件,但您可以通过将这些事件绑定到指令的 link
函数中来解决这个问题,正如您已经完成的那样。
一种更 angular 编写您的意图的方法,包装为指令,可能是以下内容。
HTML 模板
<body ng-controller="Ctrl as vm">
<pop content="vm.val1" hover="vm.val2"></pop>
</body>
JavaScript
app.controller('Ctrl', function() {
this.val1 = 'Touch or move mouse over the label';
this.val2 = '...I haz appeared!!1';
});
app.directive('pop', function() {
return {
restrict: 'E',
scope: {
content: '=',
hover: '='
},
template: '<div ng-mouseover="toggle(true)" ng-mouseleave="toggle(false)">' +
' <h4><span class="label label-default">{{ content }}</span></h4>' +
'</div>' +
'<div ng-show="show" class="alert alert-info">{{ hover }}</div>',
link: function(scope, element) {
scope.toggle = function(val) {
scope.show = val;
};
element.bind('touchstart', toggle, true);
element.bind('touchend', toggle, false);
}
};
});
相关插件在这里http://plnkr.co/edit/JjydPL