Dan*_*anH 7 javascript angularjs angularjs-controller
所以我一直在阅读控制器中的jQuery操作是不好的做法,但我不清楚为什么或如何纠正.
下面是来自Youtube教程的代码,即使是视频创建者的评论也是一个坏主意,但无法解释为什么并继续使用不良行为.
来自https://www.youtube.com/watch?v=ilCH2Euobz0#t=553s:
$scope.delete = function() {
var id = this.todo.Id;
Todo.delete({id: id}, function() {
$('todo_' + id).fadeOut();
});
};
Run Code Online (Sandbox Code Playgroud)
解决方案:
根据兰登在下面的回答,我已经得到了以下我自己的工作代码,这些代码与上面的示例代码略有不同:
var ProjectListCtrl = function ($scope, Project) {
$scope.projects = Project.query();
$scope.delete = function() {
var thisElem = this;
var thisProject = thisElem.project;
var id = thisProject.id;
Project.delete({id: id}, function() {
var idx = $scope.projects.indexOf(thisProject);
if (idx !== -1) {
thisElem.destroy('removeItem('+idx+')');
}
});
}
$scope.removeItem = function(idx) {
$scope.projects.splice(idx, 1);
}
}
app.directive('fadeOnDestroy', function() {
return function(scope, elem) {
scope.destroy = function(funcComplete) {
elem.fadeOut({
complete: function() {
scope.$apply(funcComplete)
}
});
}
}
});
Run Code Online (Sandbox Code Playgroud)
这与兰登在几个方面的答案不同.我想避免在ngClick回调中添加一个参数,所以我将其存储在thisProject.此外,示例和我的代码需要destroy从$http成功回调中调用,因此this不再相关,我将点击的元素存储在thisElem.
更新2:
进一步更新了我的解决方案,以反映funcComplete实际上并未修改原始$ scope.
处理此问题的Angular方法是通过指令.我找到了一个完美的例子来涵盖你在下面提到的内容,虽然它并不像我想的那样干净.我们的想法是创建一个用作HTML属性的指令.当元素绑定到控制器的范围时,将link触发该函数.该函数淡化元素(完全可选)并为您的控制器公开一个destroy方法以便稍后调用.
更新:根据注释修改以实际影响范围.没有兴奋的解决方案,它甚至更为jankier因为原作者complete.apply(scope)在他的destroy回调中调用,但不在this回调函数内部使用.
更新2:由于该指令是使回调异步的指令,因此在scope.$apply那里使用它可能是一个更好的主意,但请记住,如果您在指令中使用隔离范围,那可能会变得奇怪.
http://jsfiddle.net/langdonx/K4Kx8/114/
HTML:
<div ng-controller="MyCtrl">
<ul>
<li ng-repeat="item in items" fadey="500">
{{item}}
<a ng-click="clearItem(item)">X</a>
</li>
</ul>
<hr />
<button ng-click="items.push(items.length)">Add Item</button>
</div>
Run Code Online (Sandbox Code Playgroud)
JavaScript的:
var myApp = angular.module('myApp', []);
//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});
function MyCtrl($scope) {
$scope.items = [0, 1, 2];
$scope.clearItem = function(item) {
var idx = $scope.items.indexOf(item);
if (idx !== -1) {
//injected into repeater scope by fadey directive
this.destroy(function() {
$scope.items.splice(idx, 1);
});
}
};
}
myApp.directive('fadey', function() {
return {
restrict: 'A', // restricts the use of the directive (use it as an attribute)
link: function(scope, elm, attrs) { // fires when the element is created and is linked to the scope of the parent controller
var duration = parseInt(attrs.fadey);
if (isNaN(duration)) {
duration = 500;
}
elm = jQuery(elm);
elm.hide();
elm.fadeIn(duration)
scope.destroy = function(complete) {
elm.fadeOut(duration, function() {
scope.$apply(function() {
complete.$apply(scope);
});
});
};
}
};
});
Run Code Online (Sandbox Code Playgroud)
至于为什么,我认为这只是为了分离关注点和可能性.您的控制器应关注数据流和业务逻辑,而不是接口操作.理想情况下,你的指令应该是为了可用性而编写的(就像在fadey这里编写的那样.注意:我不会把它称为fadey;)).
| 归档时间: |
|
| 查看次数: |
4319 次 |
| 最近记录: |