2016-02-26 426 views
8

我想實現一個拖放使用拖放角2.我有一些項目:如何在Angular2中實現拖放?

<div class="item"></div> 

,我希望能夠拖動並在容器掉落:

<div class="container"></div> 

我在Angular 2中找不到任何有用的信息來源。我發現這個文件:https://github.com/AngularClass/angular2-examples/blob/master/rx-draggable/directives/draggable.ts我嘗試了,但是我無法使它工作,我也不完全確定它應該如何工作。

我該如何實現它?

+0

我意識到我忘了將指令添加到組件指令列表中。儘管現在似乎EventEmitter上的.toRx方法不再可用。應該如何改變? – theva

+0

從Beta 1開始,[你不再需要在發射器上調用.toRx()](http://stackoverflow.com/questions/33530726/angular-2-eventemitter-broadcasting-next-from-a-service-功能/ 33534404#33534404)。 –

+0

這是相當不錯的描述在這裏http://stackoverflow.com/a/38710223/2173016 –

回答

4

我已經使用jquery可拖動做到了 - 集成在角

import {Component, ElementRef, OnInit} from '@angular/core';' 

declare var jQuery:any; 

@Component({ 
    selector: 'jquery-integration', 
    templateUrl: './components/jquery-integration/jquery-integration.html' 
}) 
export class JqueryIntegration implements OnInit { 
    elementRef: ElementRef; 
    constructor(elementRef: ElementRef) { 
     this.elementRef = elementRef; 
    } 
    ngOnInit() { 
     jQuery(this.elementRef.nativeElement).draggable({containment:'#draggable-parent'}); 
    } 
} 

此處瞭解詳情: http://www.syntaxsuccess.com/viewarticle/using-jquery-with-angular-2.0

現場演示: http://www.syntaxsuccess.com/angular-2-samples/#/demo/jquery

+2

我寧願做Angular2而不使用jQuery。正如您在文章中所說的那樣,使用jQuery並不是Angular的做事方式。但是如果我沒有找到更好的方法,我會考慮這個解決方案。 – theva

3

我會建議使用Ng2-Dragula

它是angular2依賴項,它爲您的應用程序輕鬆提供拖放功能。

所有你需要做的就是通過npm來安裝這個依賴。

npm install ng2-dragula dragula --save 

插件包括內部的index.html和配置系統

<script src="/node_modules/ng2-dragula/bundles/ng2-dragula.js"></script> 
<link href="/node_modules/ng2-dragula/src/public/css/dragula.min.css" rel='stylesheet' type='text/css'> 
<script> 
    System.config({   
    paths:{ 
     'dragula'   : '../node_modules/dragula/dist/dragula.min.js' 
    }, 
    packages: {    
     app: { 
     format: 'register', 
     defaultExtension: 'js' 
     } 
    } 
    }); 

System.import('app/main') 
     .then(null, console.error.bind(console)); 
</script> 

進口它要使用拖放n個墨滴在組件內部,你是好去。

@Component({ 
    selector: 'sample', 
    directives: [Dragula], 
    viewProviders: [DragulaService], 
    template:` 
    <div> 
    <div class='wrapper'> 
     <div class='container' [dragula]='"first-bag"'> 
     <div>You can move these elements between these two containers</div> 
     <div>Moving them anywhere else isn't quite possible</div> 
     <div>There's also the possibility of moving elements around in the same container, changing their position</div> 
     </div> 
     <div class='container' [dragula]='"first-bag"'> 
     <div>This is the default use case. You only need to specify the containers you want to use</div> 
     <div>More interactive use cases lie ahead</div> 
     <div>Make sure to check out the <a href='https://github.com/bevacqua/dragula#readme'>documentation on GitHub!</a></div> 
     </div> 
    </div> 
    </div> 
    ` 
}) 
class Sample {} 
3

我也開始使用同樣的例子爲我的可拖動 - 並且確實讓它工作。這個例子來自angular2的早期版本,所以一些更改是必需的。退房this answer。它有一些這樣的變化。祝你好運!

我自己稍微更通用的版本是這樣的:

import {Directive, EventEmitter, HostListener, Output} from 'angular2/core'; 
import {Observable} from 'rxjs/Observable'; 

@Directive({ 
    selector: '[draggable]' 
}) 
export class DraggableDirective { 

    @Output() mousedrag: Observable<{x: number, y: number}>; 
    @Output() dragend = new EventEmitter<void>(); 
    mousedown = new EventEmitter<MouseEvent>(); 
    mousemove = new EventEmitter<MouseEvent>(); 
    dragActive = false; 

    @HostListener('document:mouseup', ['$event']) 
    onMouseup(event) { 
    if(this.dragActive) { 
     this.dragend.emit(null); 
     this.dragActive = false; 
    } 
    } 

    @HostListener('mousedown', ['$event']) 
    onMousedown(event: MouseEvent) { 
    this.mousedown.emit(event); 
    } 

    @HostListener('document:mousemove', ['$event']) 
    onMousemove(event: MouseEvent) { 
    if(this.dragActive) { 
     this.mousemove.emit(event); 
     return false; 
    } 
    } 

    constructor() { 
    this.mousedrag = this.mousedown.map((event) => { 
     this.dragActive = true; 
     return { x: event.clientX, y: event.clientY }; 
    }).flatMap(mouseDownPos => this.mousemove.map(pos => { 
     return { x: pos.clientX - mouseDownPos.x, y: pos.clientY - mouseDownPos.y }; 
    }).takeUntil(this.dragend)); 
    } 
} 

採取與少許鹽,因爲我目前正在追逐一個內存泄漏,這似乎是與此相關的指令。如果我發現問題,我會更新。

+0

你是對的 - 我正在懶惰:) – LOAS

8

試試這個:

systemjs.config: 

var map =  { 
    'app': './wwwroot/ngApp', 
    'rxjs': './wwwroot/js/libs/rxjs', 
    '@angular': './wwwroot/js/libs/@angular', 
    'dragula': './wwwroot/js/libs/dragula/dist/dragula.js', 
    'ng2-dragula': './wwwroot/js/libs/ng2-dragula' 
    }; 

var packages = { 
    'app': { main: 'main.js', defaultExtension: 'js' }, 
    'rxjs': { defaultExtension: 'js' }, 
    'dragula': { defaultExtension: 'js' }, 
    'ng2-dragula': {defaultExtension: 'js' } 
    }; 

var config = { 
    map: map, 
    packages: packages 
    }` 

然後導入

import {Dragula, DragulaService} from 'ng2-dragula/ng2-dragula'; 

而且在@Component

directives: [Dragula], viewProviders: [DragulaService] 
+3

這是一個非常好的拖放實現。我真的很喜歡你那裏的商業邏輯。沒有足夠的jquery – Ced

+0

找不到這個文件'systemjs.config',它位於何處? – praveen

14

試試這個:

function onDragStart(event, data) { 
    event.dataTransfer.setData('data', data); 
} 
function onDrop(event, data) { 
    let dataTransfer = event.dataTransfer.getData('data'); 
    event.preventDefault(); 
} 
function allowDrop(event) { 
    event.preventDefault(); 
} 
<div (drop)="onDrop($event, dropData)" (dragover)="allowDrop($event)"></div> 
<div draggable="true" (dragstart)="onDragStart($event, dragData)"></div>