angular-dragdrop icon indicating copy to clipboard operation
angular-dragdrop copied to clipboard

Reference to deeply nested callback not working

Open poshest opened this issue 9 years ago • 4 comments

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;
          }
        }
      }

poshest avatar Dec 28 '15 08:12 poshest

@poshest: Cool..! Can you send a PR? Does the fix support 3,4,..n level nesting?

codef0rmer avatar Dec 28 '15 12:12 codef0rmer

Infinity levels of nesting, yes. Never done a pull request before. Would it be easier if you just made the changes and commit from your account?

poshest avatar Dec 28 '15 15:12 poshest

@poshest: Yes, I can do it but I was asking for a PR to get you the credit for the fix :-)

codef0rmer avatar Dec 28 '15 16:12 codef0rmer

Thanks! That's very kind. But my Create Pull Request button is greyed out, and I'm too busy right now to work it out. So if you won't mind, I'm happy to forgo the credit :))

On 28 December 2015 at 17:55, codef0rmer [email protected] wrote:

@poshest https://github.com/poshest: Yes, I can do it but I was asking for a PR to get you the credit for the fix :-)

— Reply to this email directly or view it on GitHub https://github.com/codef0rmer/angular-dragdrop/issues/247#issuecomment-167602812 .

poshest avatar Dec 28 '15 19:12 poshest