Skip to content

Drag and drop across components #376

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
doender opened this issue Aug 2, 2017 · 12 comments
Closed

Drag and drop across components #376

doender opened this issue Aug 2, 2017 · 12 comments

Comments

@doender
Copy link

doender commented Aug 2, 2017

Thank you for this high quality lib!

I have encountered an issue when dragging an external element to a tree, more specifically when the external element and the tree are in different components.

For example, in the template:

<p [treeDrag]="{name: 'first'}" [treeDragEnabled]="true">Drag me!</p>

And the following relevant part of the tree's options:

actionMapping: {
   mouse: {
      drop: (tree: TreeModel, node: TreeNode, $event: any, { from, to }) => {
          // 'from' is null when dropping element outside component
      }
    }
}

This works fine when the element and the tree are in the same component.
I'm using angular-tree-component 4.0.0, angular 4.2.3 and it happens in both Chrome and Firefox.

Is there a workaround or is dragging across components currently not supported?

@adamkleingit
Copy link
Contributor

Maybe it's because TreeDraggedElement is a singleton service provided by the angular tree component module.
Are you importing the tree module in appModule?

@adamkleingit
Copy link
Contributor

If the dragged element is in a different component but under the same module - does it work?

@KeithGillette
Copy link
Contributor

KeithGillette commented Dec 1, 2017

We are experiencing the same issue with [email protected] when dragging a TreeNode between trees in components that are declared in different lazy-loaded modules. Given your comment regarding the TreeDraggedElement provider of TreeModule, @adamkleingit, I believe that Angular is providing separate non-communicating TreeDraggedElement providers for each module.

Following that insight, we have worked-around this issue by modifying the angular-tree-component source code so that we can call TreeModule.forRoot() in our AppModule to get a single, application-wide instance of TreeDraggedElement for the Angular dependency injector but still import TreeModule normally in other other (lazy-loaded) modules to get the TreeComponent declarations.

I'd be happy to submit a pull request to integrate this change into angular-tree-component so that drag-and-drop can be used in applications with lazy-loaded modules, though the simplistic approach taken in this work-around introduces breaking changes for existing users.

@adamkleingit
Copy link
Contributor

adamkleingit commented Dec 1, 2017 via email

@KeithGillette
Copy link
Contributor

KeithGillette commented Dec 1, 2017

Thanks for the fast reply @adamkleingit.

It occurs to me that it may be possible to maintain backward compatibility and meet this use case of drag-and-drop between lazy-loaded modules by creating two additional modules in addition to the existing TreeModule, giving:

  • TreeComponentModule: declares & exports all components but specifies no providers
  • TreeProviderModule: only includes providers: [TreeDraggedElement]
  • TreeModule: imports & exports TreeComponentModule & TreeProviderModule

Existing projects and new projects using only eagerly-loaded modules could continue to use TreeModule per the existing instructions. Projects with lazy-loaded modules would import TreeProviderModule in the root AppModule to get the singleton TreeDraggedElement provider and TreeComponentsModule in any module in which a TreeComponent is used.

Let me know whether you prefer the simplistic (but breaking) forRoot() approach or the backward-compatible 3-module approach.

@adamkleingit
Copy link
Contributor

adamkleingit commented Dec 7, 2017 via email

@KeithGillette
Copy link
Contributor

Yes, the issue occurs for us when dragging across TreeComponents in separate NgModules, at least one of which is being lazy-loaded, so not lazy-loading modules should provide a work-around at the expense of losing the benefits of lazy-loading. As explained in the Angular DI link in my first message, each lazy-loaded module gets its own dependency injector. Since TreeModule must be imported in each module in which the TreeComponent is used, doing so then creates multiple, non-communicating instances of the TreeDraggedElement provider.

I'll put together a Pull Request for the backward-compatible 3-module approach. Let me know if there's a particular branch/commit on which I should base this work or whether I should just fork the current release on master.

@adamkleingit
Copy link
Contributor

adamkleingit commented Dec 8, 2017 via email

@KeithGillette
Copy link
Contributor

KeithGillette commented Dec 11, 2017

I'm working on this PR, @adamkleingit, but running into the following error in the browser console when attempting to follow your contribution guidelines and test with npm run example:cli. This error occurs even with unmodified source code from the current release on master, so I think it may be related to this open Angular CLI error which occurs local libraries & the JIT compiler. Please let me know if this occurs for you, as well.

Uncaught Error: Unexpected value 'TreeModule' imported by the module 'AppModule'. Please add a @NgModule annotation.
    at syntaxError (compiler.js:485)
    at eval (compiler.js:15206)
    at Array.forEach (<anonymous>)
    at CompileMetadataResolver.getNgModuleMetadata (compiler.js:15189)
    at JitCompiler._loadModules (compiler.js:34226)
    at JitCompiler._compileModuleAndComponents (compiler.js:34187)
    at JitCompiler.compileModuleAsync (compiler.js:34081)
    at CompilerImpl.compileModuleAsync (platform-browser-dynamic.js:230)
    at PlatformRef.bootstrapModule (core.js:5573)
    at eval (main.ts:11)

@adamkleingit
Copy link
Contributor

adamkleingit commented Dec 11, 2017 via email

@KeithGillette
Copy link
Contributor

  • MacOS X 10.13.1
  • Node.JS 8.8.1
  • NPM 5.4.2

Strangely, when I execute npm run example:cli, it automatically changes example/cli/package.json as follows:

-    "angular-tree-component": "^6",
+    "angular-tree-component": "file:../..",

@KeithGillette
Copy link
Contributor

Hi, @adamkleingit,

I tried npm run example:cli off of both the HEAD of master (7.0.0) and the current release tagged commit (6.1.0) but in both cases get the same browser console error I reported earlier:

compiler.js:485 Uncaught Error: Unexpected value 'TreeModule' imported by the module 'AppModule'. Please add a @NgModule annotation.
    at syntaxError (compiler.js:485)
    at eval (compiler.js:15206)
    at Array.forEach (<anonymous>)
    at CompileMetadataResolver.getNgModuleMetadata (compiler.js:15189)
    at JitCompiler._loadModules (compiler.js:34226)
    at JitCompiler._compileModuleAndComponents (compiler.js:34187)
    at JitCompiler.compileModuleAsync (compiler.js:34081)
    at CompilerImpl.compileModuleAsync (platform-browser-dynamic.js:230)
    at PlatformRef.bootstrapModule (core.js:5573)
    at eval (main.ts:11)

I've since updated to:

  • Node.js 8.9.3
  • NPM 5.5.1

FYI, my global installs are:

Please let me know what recommendations you have for troubleshooting these errors so I can proceed with the changes for this PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants