如何在不使用 Isolate Scope Expression Binding 的情况下向 AngularJS 指令添加回调
How to add callback to AngularJS Directive without using Isolate Scope Expression Binding
定义范围以在 anuglarjs 可排序指令上添加回调函数会破坏排序功能
我找到了一个位于 jquery-ui 之上的简单指令,用于直观地对列表进行排序。我想添加一个函数回调,以便在对列表进行排序时通知我的控制器,这样我就可以调用服务器进行排序,如果在服务器上以及这种排序需要持久化。
我在我的指令中添加了一个范围对象并定义了一个回调,但是添加这个范围对象的行为打乱了排序。它实际上不再在视觉上排序。最终,我希望获悉发生了某种情况。有什么想法吗?
这个 psi-sortable 会放在 ul 标签上,它希望 ng-model 成为有问题的列表。我只是想添加一个回调,这样我就可以知道发生了什么。
angular.module('psi.sortable', [])
.value('psiSortableConfig', {
placeholder: "placeholder",
opacity: 0.8,
axis: "y",
helper: 'clone',
forcePlaceholderSize: true
})
.directive("psiSortable", ['psiSortableConfig', '$log', function (psiSortableConfig, $log) {
return {
require: '?ngModel',
/*scope: {
onSorted: '&'
},*/
link: function (scope, element, attrs, ngModel) {
if (!ngModel) {
$log.error('psiSortable needs a ng-model attribute!', element);
return;
}
var opts = {};
angular.extend(opts, psiSortableConfig);
opts.update = update;
// listen for changes on psiSortable attribute
scope.$watch(attrs.psiSortable, function (newVal) {
angular.forEach(newVal, function (value, key) {
element.sortable('option', key, value);
});
}, true);
// store the sortable index
scope.$watch(attrs.ngModel + '.length', function () {
element.children().each(function (i, elem) {
jQuery(elem).attr('sortable-index', i);
});
});
// jQuery sortable update callback
function update(event, ui) {
// get model
var model = ngModel.$modelValue;
// remember its length
var modelLength = model.length;
// rember html nodes
var items = [];
// loop through items in new order
element.children().each(function (index) {
var item = jQuery(this);
// get old item index
var oldIndex = parseInt(item.attr("sortable-index"), 10);
// add item to the end of model
model.push(model[oldIndex]);
if (item.attr("sortable-index")) {
// items in original order to restore dom
items[oldIndex] = item;
// and remove item from dom
item.detach();
}
});
model.splice(0, modelLength);
// restore original dom order, so angular does not get confused
element.append.apply(element, items);
// notify angular of the change
scope.$digest();
//scope.onSorted();
}
element.sortable(opts);
}
};
}]);
要避免添加隔离作用域,只需使用 scope.$eval
:
app.directive("psiSortable", ['psiSortableConfig', '$log', function (psiSortableConfig, $log) {
return {
require: '?ngModel',
/*scope: {
onSorted: '&'
},*/
link: function (scope, element, attrs, ngModel) {
if (!ngModel) {
$log.error('psiSortable needs a ng-model attribute!', element);
return;
}
//
//...
//
// jQuery sortable update callback
function update(event, ui) {
//...
̶s̶c̶o̶p̶e̶.̶o̶n̶S̶o̶r̶t̶e̶d̶(̶)̶;̶
scope.$eval(attrs.onSorted, {$event: event});
scope.$apply();
}
element.sortable(opts);
}
};
}]);
有关详细信息,请参阅
定义范围以在 anuglarjs 可排序指令上添加回调函数会破坏排序功能
我找到了一个位于 jquery-ui 之上的简单指令,用于直观地对列表进行排序。我想添加一个函数回调,以便在对列表进行排序时通知我的控制器,这样我就可以调用服务器进行排序,如果在服务器上以及这种排序需要持久化。
我在我的指令中添加了一个范围对象并定义了一个回调,但是添加这个范围对象的行为打乱了排序。它实际上不再在视觉上排序。最终,我希望获悉发生了某种情况。有什么想法吗?
这个 psi-sortable 会放在 ul 标签上,它希望 ng-model 成为有问题的列表。我只是想添加一个回调,这样我就可以知道发生了什么。
angular.module('psi.sortable', [])
.value('psiSortableConfig', {
placeholder: "placeholder",
opacity: 0.8,
axis: "y",
helper: 'clone',
forcePlaceholderSize: true
})
.directive("psiSortable", ['psiSortableConfig', '$log', function (psiSortableConfig, $log) {
return {
require: '?ngModel',
/*scope: {
onSorted: '&'
},*/
link: function (scope, element, attrs, ngModel) {
if (!ngModel) {
$log.error('psiSortable needs a ng-model attribute!', element);
return;
}
var opts = {};
angular.extend(opts, psiSortableConfig);
opts.update = update;
// listen for changes on psiSortable attribute
scope.$watch(attrs.psiSortable, function (newVal) {
angular.forEach(newVal, function (value, key) {
element.sortable('option', key, value);
});
}, true);
// store the sortable index
scope.$watch(attrs.ngModel + '.length', function () {
element.children().each(function (i, elem) {
jQuery(elem).attr('sortable-index', i);
});
});
// jQuery sortable update callback
function update(event, ui) {
// get model
var model = ngModel.$modelValue;
// remember its length
var modelLength = model.length;
// rember html nodes
var items = [];
// loop through items in new order
element.children().each(function (index) {
var item = jQuery(this);
// get old item index
var oldIndex = parseInt(item.attr("sortable-index"), 10);
// add item to the end of model
model.push(model[oldIndex]);
if (item.attr("sortable-index")) {
// items in original order to restore dom
items[oldIndex] = item;
// and remove item from dom
item.detach();
}
});
model.splice(0, modelLength);
// restore original dom order, so angular does not get confused
element.append.apply(element, items);
// notify angular of the change
scope.$digest();
//scope.onSorted();
}
element.sortable(opts);
}
};
}]);
要避免添加隔离作用域,只需使用 scope.$eval
:
app.directive("psiSortable", ['psiSortableConfig', '$log', function (psiSortableConfig, $log) {
return {
require: '?ngModel',
/*scope: {
onSorted: '&'
},*/
link: function (scope, element, attrs, ngModel) {
if (!ngModel) {
$log.error('psiSortable needs a ng-model attribute!', element);
return;
}
//
//...
//
// jQuery sortable update callback
function update(event, ui) {
//...
̶s̶c̶o̶p̶e̶.̶o̶n̶S̶o̶r̶t̶e̶d̶(̶)̶;̶
scope.$eval(attrs.onSorted, {$event: event});
scope.$apply();
}
element.sortable(opts);
}
};
}]);
有关详细信息,请参阅