app.js
App = Em.Application.create();
App.IndexRoute = Em.Route.extend({
model: function(){
return {
newTasks: Em.A([
{id: 1, name: "Task 1"},
{id: 2, name: "Task 2"},
{id: 3, name: "Task 3"}
]),
inProgressTasks: Em.A([
{id: 4, name: "Task 4"},
{id: 5, name: "Task 5"}
]),
doneTasks: Em.A([
{id: 6, name: "Task 6"}
])
};
}
});
App.IndexController = Em.Controller.extend({
actions: {
moveTask: function(taskID, from, to){
var model = this.get('model');
var task = model[from].findProperty('id', parseInt(taskID, 10));
model[to].pushObject(task);
model[from].removeObject(task);
}
}
});
App.TaskContainerComponent = Em.Component.extend({
classNames: ['col-xs-4', 'taskContainer'],
isOverdrop: false,
classNameBindings: ['isOverdrop:isOverdrop'],
setOverdropIfNotOriginator: function(event, valueToSet){
var data = JSON.parse(event.dataTransfer.getData('text/data'));
if(data.stage !== this.get('stage')) {
this.set('isOverdrop', valueToSet);
}
},
dragEnter: function(event) {
this.setOverdropIfNotOriginator(event, true);
},
dragLeave: function(event){
this.setOverdropIfNotOriginator(event, false);
},
dragOver: function(event){
this.setOverdropIfNotOriginator(event, true);
event.preventDefault();
},
drop: function(event) {
var data = JSON.parse(event.dataTransfer.getData('text/data'));
if(data.stage === this.get('stage')) return;
// from: data.stage, to: this.get('stage')
this.sendAction('action', data.id, data.stage, this.get('stage'));
this.set('isOverdrop', false);
}
});
App.DragTaskComponent = Em.Component.extend({
dragStart: function(event) {
var data = { id: this.get('task.id'), stage: this.get('stage')};
event.dataTransfer.setData('text/data', JSON.stringify(data));
}
});
的index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Mini Scrumboard</title>
<link href="http://getbootstrap.com/dist/css/bootstrap.css" rel="stylesheet" type="text/css" />
<link rel="stylesheet" href="css/normalize.css">
<link rel="stylesheet" href="css/style.css">
</head>
<body>
<script type="text/x-handlebars" data-template-name="index">
<div class="contents">
<div class="row">
{{ task-container containerTitle="New" stage="newTasks" tasks=model.newTasks
action="moveTask" on="drop"}}
{{ task-container containerTitle="In Progress" stage="inProgressTasks"
tasks=model.inProgressTasks action="moveTask" on="drop" }}
{{ task-container containerTitle="Done" stage="doneTasks" tasks=model.doneTasks
action="moveTask" on="drop" }}
</div>
<br>
<br>
</div>
</script>
<!-- Properties: task, stage -->
<script type="text/x-handlebars" id="components/drag-task">
<div class="task" draggable="true">
{{task.name}}
</div>
</script>
<!-- Properties: containerTitle, stage, tasks -->
<script type="text/x-handlebars" id="components/task-container">
<h3>{{containerTitle}}</h3>
{{#each task in tasks}}
{{drag-task task=task stage=stage}}
{{/each}}
</script>
<script src="js/libs/jquery-1.10.2.js"></script>
<script src="js/libs/handlebars-1.1.2.js"></script>
<script src="js/libs/ember-1.5.1.js"></script>
<script src="js/app.js"></script>
<!-- to activate the test runner, add the "?test" query string parameter -->
<script src="tests/runner.js"></script>
</body>
</html>
我在本地方框上工作得非常好,但在jsbin上有错误。
http://emberjs.jsbin.com/movex/4/edit?html,css,js,output
我猜这个问题与解析拖放输出有关,但不知道该怎么做。
非常感谢任何帮助......
更新:JSBin版本甚至在Mac上的FF上工作正常,但在Safari或Chrome上却没有...... :(
答案 0 :(得分:5)
它不起作用的原因是因为the drag and drop specifications工作的意外方式。问题是,在drag
,dragEnter
,dragLeave
,dragOver
和dragEnd
事件中,dragTransfer数据处于受保护模式。这又是根据规范的意思。
数据本身不可用,无法添加新数据。
似乎Mozilla运用了一些常识,并没有按照规范实施拖放操作。这解释了为什么它在Firefox中为你工作,但没有其他地方。
为了让你的jsbin工作,我在你的索引控制器中添加了一个theData
元素,并根据它设置并获取了JSON值。