Open
Description
In this Plunkr, dropping causes an error, because Dragdrop can't find a function nested deeper than two levels from the $scope. Eg
onDrop: 'fnDrop'
is OK
onDrop: 'dd.fnDrop'
is OK
onDrop: 'dd.fns.fnDrop'
breaks
If you use "MyController as vm" syntax, it breaks Dragdrop can't find a function nested deeper than ONE level from the "as" object. Eg
onDrop: 'vm.dd.fnDrop'
breaks
This fixes it (Plunkr)
var objExtract = extract(callbackName),
fnString = objExtract.fnString,
args = [event, ui].concat(objExtract.args);
// call either $scoped method i.e. $scope.dropCallback or constructor's method i.e. this.dropCallback.
// Removing scope.$apply call that was performance intensive (especially onDrag) and does not require it
// always. So call it within the callback if needed.
return (nestedObjGet(scope, fnString)).apply(scope, args);
function extract(callbackNamecallbackName) {
var atStartBracket = callbackName.indexOf('(') !== -1 ? callbackName.indexOf('(') : callbackName.length,
atEndBracket = callbackName.lastIndexOf(')') !== -1 ? callbackName.lastIndexOf(')') : callbackName.length,
args = callbackName.substring(atStartBracket + 1, atEndBracket), // matching function arguments inside brackets
fnString = callbackName.substr(0, atStartBracket);
return {
args: $.map(args && args.split(',') || [], function(item) { return [$parse(item)(scope)]; }),
fnString: fnString
}
}
function nestedObjGet(obj, nestedAttr) {
if (obj === undefined) return undefined;
var arrAttrTree = nestedAttr.split('.');
for (var bit = 0; bit < arrAttrTree.length; bit++) {
obj = obj[arrAttrTree[bit]];
if (bit < arrAttrTree.length - 1) {
if (!obj) return undefined;
} else {
return obj;
}
}
}