【问题标题】:Fineuploader button missed after moving sortable table. Plugin elements missed in sortable table if row movedFineuploader 按钮在移动可排序表后丢失。如果行移动,可排序表中的插件元素会丢失
【发布时间】:2013-07-16 17:17:27
【问题描述】:

我一直在使用 knockout.js 和 knockout-sortable.js。为了创建一个可排序的表。 该表的其中一列应该上传图片,并且仍然可以对表进行排序。 上传工作正常,但是当我对表格进行排序时,精细上传器的按钮以及所有属性都丢失了。

小提琴:http://jsfiddle.net/XdevK/6/

重现步骤:

  1. 点击添加资产
  2. 再次单击添加资产。
  3. 将第二个资产移动到第一个位置。 错过了 Fineuploader 按钮。

实际发生的情况是 div 内容在排序完成后被删除。

JS代码:

var CommunityAsset = function(value, description, name) {
        this.Value = value;  
        this.Description = ko.observable(description);
        this.Name = "fineUploader" + name;            
    }
    var viewOverview = function()
    {
        var self = this;

        self.communityAssets = ko.observableArray();

        self.clearAsset = function(data, event) {

               self.communityAssets.remove(data);   

        };

        self.Uploaders = {};
        self.addAsset = function() {
            var name = self.communityAssets().length;
            var asset = new CommunityAsset("http://placehold.it/240x160", "", name);                    
            self.communityAssets.push(asset);
            createFineUploader(name);
        };        
        self.addAssetWithParams = function(value, description, name) {            
            var asset = new CommunityAsset(value, description, name);        
            self.communityAssets.push(asset);
            createFineUploader(name);


        };        
    }
var vc = new viewOverview();
vc.addAssetWithParams("http://placehold.it/240x160", "Hola",0);

ko.applyBindings(vc, $("#communityOverview")[0]);    




 function createFineUploader(intIndex)
    {
        vc.Uploaders[intIndex] = new qq.FineUploader({
                            element: $('#fineUploader'+intIndex)[0],
                            request: {
                                endpoint: '/Communities/FileUpload'
                            },
                            autoUpload: true,
                            sizeLimit: 4000000, // max size
                            validation: {
                                allowedExtensions: ['jpeg', 'jpg', 'gif']
                            },                
                            text: {
                                uploadButton: '<i class="icon-upload icon-white"></i> Upload a file'
                            },
                            multiple: false,
                            template: '<div class="qq-uploader ">' +
                                    '<pre class="qq-upload-drop-area "><span>{dragZoneText}</span></pre>' +
                                    '<div class="qq-upload-button btn btn-success" style="width: auto;">{uploadButtonText}</div>' +
                                    '<ul class="qq-upload-list" style="margin-top: 10px; text-align: center;"></ul>' +
                                '</div>',
                            classes: {
                                success: 'alert alert-success',
                                fail: 'alert alert-error'
                            },
                            callbacks: {
                                onComplete: function(id, name, response) {      
                                    if (response.success) 
                                    {
                                        var asset = ko.utils.arrayFirst(vc.communityAssets(), function(currentAsset) {
                                            return currentAsset.Name == "fineUploader"+intIndex; // <-- is this the desired seat?
                                        });

                                        // asset found?
                                        if (asset) {
                                            asset.Value = response.path;                                            
                                        }                                     
                                    }
                                }
                            },
                            debug: true
                        });

    }

HTML

<div class="tab-pane" id="communityOverview"> 
<table class="table" >
                                <thead>
                                    <tr>
                                      <th>Sort Order</th>
                                      <th>Community Overview Image</th>
                                      <th>Community Overview Image Description</th>                  
                                    </tr>
                                </thead>
                                <tbody  data-bind="sortable: communityAssets">
                                    <tr>
                                        <td class="item"><span data-bind="text: $index" ></span>                     
                                        </td>
                                        <td class="item">                        
                                            <div class="image-options">
                                                <div class="control-group">                                                                                     
                                                    <div class="controls">
                                                        <img  style="width:240px; height:160px;"  data-bind="attr:{src: Value}" />                                                      
                                                    </div>
                                                    <br />                                                                                                        
                                                    <div data-bind="attr: {id:Name}"></div>
                                                </div>   
                                            </div><!-- .image-options -->
                                            <a href="Javascript:void(0);" data-bind="click: $root.clearAsset ">Delete Asset</a>
                                        </td>
                                        <td class="item">
                                            <textarea class="input-block-level" rows="11" cols="3" data-bind="value: Description"></textarea>                                            
                                        </td>                  
                                    </tr>              
                                </tbody>
                            </table>
    <a href="#" data-bind="click: addAsset">Add Task</a>                                
</div>

我认为实际发生的是可排序重新创建表。这意味着我应该在排序的回调上运行fineuploader 库的重建。

排序完成后,如何让按钮保持原样?

【问题讨论】:

  • 您需要创建一个自定义绑定处理程序并将上传器创建移动到其 init 函数中...
  • 你有什么问题?
  • 为什么不只有一个上传器实例,并为每个上传的文件对它放置在页面上的
  • 元素进行排序?
  • @nemesv 如何创建绑定处理程序?
  • 标签: knockout.js knockout-2.0 fine-uploader knockout-sortable


    【解决方案1】:

    我决定重新创建 fileUploader(这可能发生在任何其他插件插入到可排序表中)。

    这很容易。

    这是代码(不在 jsfiddle 中,因为我会浪费时间制作场景)。

    HTML

    <table class="table">
    <thead>
    <tr>
        <th>
            Sort Order
        </th>
        <th>
            Community Overview Image
        </th>
        <th>
            Community Overview Image Description
        </th>
    </tr>
    </thead>
    <tbody data-bind="sortable: communityAssets">
    <tr>
        <td class="item">
            <span data-bind="text: $index"></span>
        </td>
        <td class="item">
            <div class="image-options">
                <div class="control-group">
                    <div class="controls">
                        <img style="width:240px; height:160px;" data-bind="attr:{src: URL}"/>
                    </div>
                    <br/>
                    <div data-bind="attr: {id: 'fineUploader' + Name}">
                    </div>
                </div>
            </div>
            <!-- .image-options -->
            <a href="Javascript:void(0);" data-bind="click: $root.clearAsset ">Delete Asset</a>
        </td>
        <td class="item">
            <textarea class="input-block-level" rows="11" cols="3" data-bind="value: Description"></textarea>
        </td>
    </tr>
    </tbody>
    </table>
    

    Javascript:

     var CommunityAsset = function(value, description, name, url) {
            this.URL = url;
            this.Value = value;  
            this.Description = ko.observable(description);
            this.Name = name;  
            this.FileName  = "";
            this.FileSize = "";          
        }
        var viewOverview = function()
        {
            var self = this;
    
            self.communityAssets = ko.observableArray();
    
            self.clearAsset = function(data, event) {
    
                   self.communityAssets.remove(data);   
    
            };
    
            self.Uploaders = {};
            self.addAsset = function() {
                var name = self.communityAssets().length;
                var asset = new CommunityAsset("", "", name, "http://placehold.it/240x160");                    
                self.communityAssets.push(asset);
                createFineUploader(name);
            };
    
    
        self.addAssetWithParams = function(value, description, name, url) {            
            var asset = new CommunityAsset(value, description, name, url);        
            self.communityAssets.push(asset);
    
        };       
        self.recreateUploaders = function(arg) {   
            createFineUploader(arg.item.Name);
            if (arg.item.FileName != "")
            {
                $("#fineUploader"+arg.item.Name+" .qq-upload-list").append('<li class=" alert alert-success"><span class="qq-upload-file">'+arg.item.FileName+
                '</span><span class="qq-upload-size" style="display: inline;">'+arg.item.FileSize+'</span></li>');
            }            
    
    function createFineUploader(intIndex)
    {
        vc.Uploaders[intIndex] = new qq.FineUploader({
                            element: $('#fineUploader'+intIndex)[0],
                            request: {
                                endpoint: '/Communities/FileUpload'
                            },
                            autoUpload: true,
                            sizeLimit: 4000000, // max size
                            validation: {
                                allowedExtensions: ['jpeg', 'jpg', 'gif']
                            },                
                            text: {
                                uploadButton: '<i class="icon-upload icon-white"></i> Upload a file'
                            },
                            multiple: false,
                            template: '<div class="qq-uploader ">' +
                                    '<pre class="qq-upload-drop-area "><span>{dragZoneText}</span></pre>' +
                                    '<div class="qq-upload-button btn btn-success" style="width: auto;">{uploadButtonText}</div>' +
                                    '<ul class="qq-upload-list" style="margin-top: 10px; text-align: center;"></ul>' +
                                '</div>',
                            classes: {
                                success: 'alert alert-success',
                                fail: 'alert alert-error'
                            },
                            callbacks: {
                                onComplete: function(id, name, response) {      
                                    if (response.success) 
                                    {
                                        var asset = ko.utils.arrayFirst(vc.communityAssets(), function(currentAsset) {
                                            return currentAsset.Name == intIndex; // <-- is this the desired seat?
                                        });
    
                                        if (asset) {
                                            var number = response.size;
                                            var size = "";
                                            if (number >= 1048576)
                                            {   
                                                number = number / 1048576;
                                                size = "MB";
                                            }
                                            else
                                            {
                                                number = number / 1024;
                                                size = "kB";
    
                                            }
                                            asset.FileSize = number.toFixed(1) + "" + size;
                                            asset.FileName = response.fileName;
                                            asset.Value = response.path;
                                        }                                     
                                    }
                                }
                            },
                            debug: true
                        });
    
    }              
         }; 
    }
    var vc = new viewOverview();  
    ko.bindingHandlers.sortable.afterMove  = vc.recreateUploaders;
    ko.applyBindings(vc, $("#communityOverview")[0]);
    

    神奇的是ko.bindingHandlers.sortable.afterMove = vc.recreateUploaders; 因此,在移动一行后,我们重新创建插件创建。 我添加了 FileName 的一部分,这样做是因为如果您正确上传了文件,如果行被移动,文件名的标签也会被删除,因此这将再次添加 FileName 标签。

    希望对某人有所帮助!

    【讨论】:

    • 如果您已经在使用 jQuery,为什么不使用 Fine Uploader jQuery 插件包装器?
    猜你喜欢
    相关资源
    最近更新 更多
    热门标签