如何将 HTML5 拖放与 KnockoutJS 结合使用?

发布于 2024-12-01 18:24:29 字数 1345 浏览 0 评论 0原文

我似乎无法绑定到 html5 拖放事件。

这是模板的示例:

<script id="tabsTemplate" type="text/html">
    <div class="dropzone" for="tab"
        data-bind="event:{dragover: function(event){event.preventDefault();},
                          dragenter: function(event){event.target.addClass('dragover'); event.preventDefault();},
                          dragleave: function(event){event.target.removeClass('dragover'); event.preventDefault();}}
                          drop: function(event){console.log('blahblah!')}"></div>
    <h1 class="tab" draggable="true"
      data-bind="attr: {selected: $data.name === $item.selected()},
                 click: function(){$item.selected($data.name)},
                 event:{ dragstart: function(event){console.log('blah!!')},
                         dragend: function(event){document.getElementsByClassName('dragover')[0].removeClass('dragover')}}">
        ${name}

        <img src="icons/close-black.png" class="close button" role="button"
            data-bind="click: function(e){$item.close($data)}">
    </h1>
</script>

我所拥有的应该按预期工作......只要我将它们设为正常的内联,它就可以。但是,其他绑定就不起作用了!

我收到此错误消息:

未捕获的语法错误:意外的标记“||” jquery-tmpl.js:10

这是怎么回事?我做错了什么吗?

I can't seem to bind to html5 drag and drop events.

Here's an example of from a template:

<script id="tabsTemplate" type="text/html">
    <div class="dropzone" for="tab"
        data-bind="event:{dragover: function(event){event.preventDefault();},
                          dragenter: function(event){event.target.addClass('dragover'); event.preventDefault();},
                          dragleave: function(event){event.target.removeClass('dragover'); event.preventDefault();}}
                          drop: function(event){console.log('blahblah!')}"></div>
    <h1 class="tab" draggable="true"
      data-bind="attr: {selected: $data.name === $item.selected()},
                 click: function(){$item.selected($data.name)},
                 event:{ dragstart: function(event){console.log('blah!!')},
                         dragend: function(event){document.getElementsByClassName('dragover')[0].removeClass('dragover')}}">
        ${name}

        <img src="icons/close-black.png" class="close button" role="button"
            data-bind="click: function(e){$item.close($data)}">
    </h1>
</script>

What I have should work as expected... and it does as long as I make them normal inline ones. However, then the other bindings don't work!

I am getting this error message:

Uncaught SyntaxError: Unexpected token '||' jquery-tmpl.js:10

What's going on here? Is there something I'm doing wrong?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

爱格式化 2024-12-08 18:24:29

好的,我已经解决了。看来我错过了文档中所说的,在淘汰赛中,默认情况下它会使所有事件阻止默认/返回 false。所以我所要做的就是让我的 Dragstart 处理程序返回 true,现在它可以工作了。唷!!

OK, I have worked it out. It seems I missed in the documentation where it said that in knockout, by default it makes all events prevent default / return false. So all I had to do was make my dragstart handler return true, and now it works. Phew!!

怎会甘心 2024-12-08 18:24:29

对于那些(像我一样)需要 SSCCE 工作的人;该解决方案遵循 [cybermotron] 建议,还修复了处理程序需要参数数据事件的问题。

http://jsfiddle.net/marrok/m63aJ/

HTML

<script type="application/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>

<ul id="people" data-bind='template: { name: "personTmpl", foreach: people }'>
</ul>
<div class="trash" data-bind ="visible:dragging, event:{
       dragover: function(data, event){
          event.preventDefault();
       },
       drop: function(data, event){
          console.log('trash', $root.drag_start_index())
          $root.trash($root.drag_start_index())     
          event.preventDefault();
       }
}"> <span>DELETE</span> </div> 

<script id="personTmpl" type="text/html">
    <li class="draggable" draggable="true" data-bind="event:{
      dragstart:   function(data, event){ 
                    $(event.target).addClass('dragSource')
                    $root.drag_start_index($index());
                    return $(event.target).hasClass('draggable');},    

       dragend:   function(data, event){  
                   $root.drag_start_index(-1);
                   $(event.target).removeClass('dragSource')
                   return true;
       },    
       dragover:  function(data, event){event.preventDefault();},
       dragenter: function(data, event){
                $root.drag_target_index($index());
                var element = $(event.target)
                if(element.hasClass('draggable'))
                     element.toggleClass('dragover'); 
                event.preventDefault();
    },
       dragleave: function(data, event, $index){
                var element = $(event.target)
                if(element.hasClass('draggable'))
                     element.toggleClass('dragover');
                event.preventDefault();
    },
       drop: function(data, event){
                $(event.target).removeClass('dragover'); 
                console.log('swap', $root.drag_start_index(),  $root.drag_target_index() )
                $root.swap($root.drag_start_index(),  $root.drag_target_index())
               }
             }">

        <span data-bind='text: name'></span>
    </li>
</script>

淘汰赛

var Person = function(name) {
    this.name = ko.observable(name);

};

var PeopleModel = function() {
    var self = this;

    self.drag_start_index = ko.observable();
    self.drag_target_index = ko.observable();
    self.dragging = ko.computed(function() {
        return self.drag_start_index() >= 0;
    });
    self.people = ko.observableArray([
        new Person("Oleh"), new Person("Nick C."), new Person("Don"), new Person("Ted"), new Person("Ben"), new Person("Joe"), new Person("Ali"), new Person("Ken"), new Person("Doug"), new Person("Ann"), new Person("Eve"), new Person("Hal")]);


    self.trash = function(index) {
        self.people.splice(index, 1)
    }
    self.swap = function(from, to) {
        if (to > self.people().length - 1 || to < 0) return;

        var fromObj = self.people()[from];
        var toObj = self.people()[to];
        self.people()[to] = fromObj;
        self.people()[from] = toObj;
        self.people.valueHasMutated()
    }
};
ko.applyBindings(new PeopleModel());​

For those (like me) who need a SSCCE working; the solution follow's [cybermotron] suggestion, also fixes an issue where handlers expect prarameters data and event.

http://jsfiddle.net/marrok/m63aJ/

HTML

<script type="application/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js"></script>

<ul id="people" data-bind='template: { name: "personTmpl", foreach: people }'>
</ul>
<div class="trash" data-bind ="visible:dragging, event:{
       dragover: function(data, event){
          event.preventDefault();
       },
       drop: function(data, event){
          console.log('trash', $root.drag_start_index())
          $root.trash($root.drag_start_index())     
          event.preventDefault();
       }
}"> <span>DELETE</span> </div> 

<script id="personTmpl" type="text/html">
    <li class="draggable" draggable="true" data-bind="event:{
      dragstart:   function(data, event){ 
                    $(event.target).addClass('dragSource')
                    $root.drag_start_index($index());
                    return $(event.target).hasClass('draggable');},    

       dragend:   function(data, event){  
                   $root.drag_start_index(-1);
                   $(event.target).removeClass('dragSource')
                   return true;
       },    
       dragover:  function(data, event){event.preventDefault();},
       dragenter: function(data, event){
                $root.drag_target_index($index());
                var element = $(event.target)
                if(element.hasClass('draggable'))
                     element.toggleClass('dragover'); 
                event.preventDefault();
    },
       dragleave: function(data, event, $index){
                var element = $(event.target)
                if(element.hasClass('draggable'))
                     element.toggleClass('dragover');
                event.preventDefault();
    },
       drop: function(data, event){
                $(event.target).removeClass('dragover'); 
                console.log('swap', $root.drag_start_index(),  $root.drag_target_index() )
                $root.swap($root.drag_start_index(),  $root.drag_target_index())
               }
             }">

        <span data-bind='text: name'></span>
    </li>
</script>

Knockout

var Person = function(name) {
    this.name = ko.observable(name);

};

var PeopleModel = function() {
    var self = this;

    self.drag_start_index = ko.observable();
    self.drag_target_index = ko.observable();
    self.dragging = ko.computed(function() {
        return self.drag_start_index() >= 0;
    });
    self.people = ko.observableArray([
        new Person("Oleh"), new Person("Nick C."), new Person("Don"), new Person("Ted"), new Person("Ben"), new Person("Joe"), new Person("Ali"), new Person("Ken"), new Person("Doug"), new Person("Ann"), new Person("Eve"), new Person("Hal")]);


    self.trash = function(index) {
        self.people.splice(index, 1)
    }
    self.swap = function(from, to) {
        if (to > self.people().length - 1 || to < 0) return;

        var fromObj = self.people()[from];
        var toObj = self.people()[to];
        self.people()[to] = fromObj;
        self.people()[from] = toObj;
        self.people.valueHasMutated()
    }
};
ko.applyBindings(new PeopleModel());​
雪落纷纷 2024-12-08 18:24:29

您可能遇到与此处,尽管它指的是嵌套模板:

警告

如果您将 templateOptions 从嵌套模板传递到模板绑定(因此,从模板内指定模板绑定),请特别注意您的语法。如果您的绑定如下所示,您将遇到一个问题:

 <div data-bind="template: { name: 'items', data: newItems, templateOptions: { header: “New Items!”}}"></div> 

jQuery 模板插件会被绑定末尾的 }} 混淆,因为这是其语法的一部分。在大括号之间添加一个空格就可以了。希望这可以防止某人遭受一些不必要的挫败感。

 <div data-bind="template: { name: 'items', data: newItems, templateOptions: { header: “New Items!”} }"></div>

You might have the same problem as mentioned here, although it refers to nested templates:

Warning

If you are passing templateOptions to the template binding from a nested template (so, specifying a template binding from within a template), then pay special attention to your syntax. You will encounter a problem, if your binding looks like this:

 <div data-bind="template: { name: 'items', data: newItems, templateOptions: { header: “New Items!”}}"></div> 

The jQuery Templates plugin gets confused by the }} at the end of your binding, since that is part of its syntax. Adding a space between your braces will work fine. Hopefully this prevents someone from a little unnecessary frustration.

 <div data-bind="template: { name: 'items', data: newItems, templateOptions: { header: “New Items!”} }"></div>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文