动态创建一行JS淘汰赛 [英] dynamic row creation knockout js

查看:91
本文介绍了动态创建一行JS淘汰赛的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用淘汰赛JS想创建一个表,将有4rows和4coulmns。下面是我的数组里面会有这将需要在表内将投入16个元素。

  / * ------------------------------------ ---------------------------------- * /
/ *视图模型* /
/ * ------------------------------------------------ ---------------------- * /
功能视图模型(){
    VAR自我=这一点;
    self.items = ko.observableArray([1.JPG
                                      2.JPG
                                      3.JPG
                                      4.JPG
                                      5.JPG
                                      6.JPG
                                      ]);
    self.itemRows = ko.computed(函数(){//计算动态基础上的项目的行
        变种行= [];
        变种数= 0;
        变种项= self.items(); //获得该项目的数组
        无功电流= [];
        对(在项目变种I)
        {
            VAR项目=项目[I]
            current.push(项目);
            算上++;            如果(计数== 4)
            {
                计数= 0;
                rows.push(电流);
                电流= []; //一个阵列
            }
        }        如果(current.length大于0)
        {
            rows.push(电流);
        }        返回行;
    });    self.bindSort =功能(){        变种的startIndex = -1;
        VAR sortableSetup = {
         启动:函数(事件,UI)
         {
          的startIndex = ui.item.index();
         },
         停止:函数(事件,UI)
         {
          变种newIndex = ui.item.index();
          如果(的startIndex -1个)
          {
              self.from = ko.observable(的startIndex);
              self.to = ko.observable(newIndex);
              VAR伊藤= parseInt函数(self.to());
          变种I来自= parseInt函数(self.from());
          从= self.items()[I来自]变种;
              VAR为= self.items()[伊藤];
              self.items()[ITO] =从;
                  self.items()[I来自] =来;
                  //警报('前');
                  //警报(从);
                  //警报(到);
                  VAR FROMA = self.items()[I来自];
              VAR TOA = self.items()[伊藤];
              //警报('')之后;
          //警报(FROMA);
                  //警报(TOA);
              self.items.remove(从);
              self.items.splice(newIndex,0,TOA);
               self.items.remove(到);
                self.items.splice(的startIndex,0,FROMA);
                          //ui.item.remove();
               self.items.valueHasMutated();          }         }
        };
        $(。fruitList)排序(sortableSetup)。    };}/ * ------------------------------------------------ ---------------------- * /
/ * KO HTML绑定* /
/ * ------------------------------------------------ ---------------------- * /
$(文件)。就绪(函数(){    //创建视图模型
    VAR模型=新视图模型();    //呼吁jQuery UI的设置绑定方法
    model.bindSort();    //绑定阁与HTML属性
    ko.applyBindings(模型);});

和试图做到这一点在HTML中,

 <表中的数据绑定=的foreach:itemRows>
              < TR类=fruitList数据绑定=的foreach:$数据>
                  < TD>< IMG数据绑定=ATTR:{SRC:$数据}/>< / TD>
              < / TR>
        < /表>

我不能够得到数组的长度,也是我怎么可以打破循环一次,它会在第一个4 TDS,然后创建第二行..任何建议???

更新:

下面code似乎并不当我使用排序工作,

 启动:函数(事件,UI)
     {
      的startIndex = ui.item.index();
     },
     停止:函数(事件,UI)
     {
      变种newIndex = ui.item.index();


解决方案

更新:移动到下方为可排序版本

非排序版本

我创建了一个的jsfiddle这似乎满足您的要求,您编辑和之前提到的排序:的http://的jsfiddle .NET / fENSD / 4 /

我所做的就是创建一个计算观察到的是观察你的项目观察到并返回,你想为你的表格渲染形状的嵌套数组。这是不是最有效的功能,但也有一些工作,你很可能减少上获得分配的数组数(目前,5左右将为每次更新时一个4x4格中创建):

  self.items = ko.observableArray([图像/ 1.JPG,图像/ 2.JPG,图像/ 3.JPG,图像/ 4。 JPG,图像/ 5.JPG,图像/ 6.JPG]);self.itemRows = ko.computed(函数(){//计算动态基础上的项目的行
    变种行= [];
    变种数= 0;
    变种项= self.items(); //获得该项目的数组
    无功电流= [];
    对(在项目变种I)
    {
        VAR项目=项目[I]
        current.push(项目);
        算上++;        如果(计数== 4)
        {
            计数= 0;
            rows.push(电流);
            电流= []; //一个阵列
        }
    }    如果(current.length大于0)
    {
        rows.push(电流);
    }    返回行;
});

这样的表呈现像这样:

 <表中的数据绑定=的foreach:itemRows>
    < TR数据绑定=的foreach:$数据>
        < TD>< IMG数据绑定=ATTR:{SRC:$数据}/>< / TD>
    < / TR>
< /表>

本的jsfiddle包括增加一个项目到项目可观测和表正在更新的一个例子,以反映以及如果你想看到在行动。也有在的jsfiddle的一种方式的例子,你可以得到的物品数组的长度(数据绑定=TEXT:项目()的长度

可排序版本

这是一个相当的变化,但我设法排序工作,以及。以从jQuery UI的网站的例子,我得到了以下内容:

http://jsfiddle.net/fENSD/11/

有非常困难的排序表,所以jQuery UI的例子中实际使用该有与每个元件占用了一定宽度的定义的宽度的列表。这有效地创建表。我想,既然你使用的图像,你可以让他们都完全一样的大小。

要做到这一点,我有一些CSS像这样:

  #items {列表样式类型:无;保证金:0;填充:0;宽度:200像素; }
#it​​ems李{宽度:48像素;保证金:0像素;填充:0像素;浮动:左;文本对齐:中心;高度:48像素; }

然后,我创建了一个合适的结合处理,像这样:

  ko.bindingHandlers ['排序'] = {
    初始化:功能(元素,valueAccessor){
        变量$元= $(元);
        无功可观察= valueAccessor();
        VAR值= ko.utils.unwrapObservable(看到);
        $ element.sortable({
            停止:函数(事件,UI){
                。VAR preV = ui.item preV();
                VAR数据= ko.dataFor(ui.item [0]);
                变种索引= 0;
                如果(prev.length大于0){
                    //不是第一个项目
                    VAR prevData = ko.dataFor(preV [0]);
                    VAR指数= value.indexOf(prevData)+ 1;
                }
                变种oldIndex = value.indexOf(数据);
                value.splice(oldIndex,1);
                value.splice(指数,0,数据);
                observable.valueHasMutated();
            }
        });
    }
};

每当排序更新,它修改传入绑定可观察的数组。 注意:这是令人难以置信的unrobust,需要检查告诉它,它的价值已经变异之前,以确保传递的值实际上是一个可观察

视图模型看起来像这样:

 功能视图模型(){
    VAR自我=这一点;    self.items = ko.observableArray([1,2,3,4,5,6,7,8,9,10, 11,12,13]);    self.items.subscribe(函数(值){
        的console.log(值); //这是这样你就可以看到阵列确实正在重新排序
    });    self.add =功能(){
        self.items.push(另一回事);
    };
}

和渲染:

 < UL ID =项目数据绑定=排序:项目的foreach:项目>
    <立GT;< IMG数据绑定=ATTR:{SRC:$数据}/>< /李>
< / UL>

这种方法的局限性,如果你的项目是不同的大小,可排序的顺序看起来比实际重新在内存psented $ P $有点不同。然而,提供您所有的元素都是相同的大小,它应该只是罚款。另一个问题是,这种不重复的项目很好地工作。然而,为了解决这个应该代替普通老式串使得每个元素包含一个值(甚至可观察到的值)的物体的简单的事情。

Using knockout js am trying to create a table which will have 4rows and 4coulmns. Below is my array which will have 16 elements which will be needed to be put inside the table.

    /*----------------------------------------------------------------------*/
/* View Model                                                           */
/*----------------------------------------------------------------------*/
function ViewModel() {
    var self = this;
    self.items = ko.observableArray(["1.jpg", 
                                      "2.jpg", 
                                      "3.jpg", 
                                      "4.jpg",
                                      "5.jpg",
                                      "6.jpg"
                                      ]);
    self.itemRows = ko.computed(function () { //computes the rows dynamically based on items
        var rows = [];
        var count = 0;
        var items = self.items(); //get the item array
        var current = [];
        for(var i in items)
        {
            var item = items[i];
            current.push(item);
            count++;

            if (count == 4)
            {
                count = 0;
                rows.push(current);
                current = []; //next array
            }
        }

        if (current.length > 0)
        {
            rows.push(current);
        }

        return rows;
    });

    self.bindSort = function() {

        var startIndex = -1;         
        var sortableSetup = {        
         start: function (event, ui)
         {         
          startIndex = ui.item.index();
         },


         stop: function (event, ui) 
         {      
          var newIndex = ui.item.index();        
          if (startIndex > -1) 
          {
              self.from = ko.observable(startIndex);
              self.to = ko.observable(newIndex);
              var iTo = parseInt(self.to());
          var iFrom = parseInt(self.from());
          var from = self.items()[iFrom];
              var to = self.items()[iTo];
              self.items()[iTo] = from;
                  self.items()[iFrom] = to;
                  //alert('before');
                  // alert(from);
                  // alert(to);
                  var fromA = self.items()[iFrom];
              var toA = self.items()[iTo]; 
              //alert('after');
          //alert(fromA);
                  // alert(toA);
              self.items.remove(from);               
              self.items.splice(newIndex, 0, toA);
               self.items.remove(to); 
                self.items.splice(startIndex, 0, fromA);
                          //ui.item.remove();
               self.items.valueHasMutated();

          }

         }
        };


        $(".fruitList").sortable( sortableSetup );                           

    };

}   

/*----------------------------------------------------------------------*/
/* KO HTML Binding                                                      */
/*----------------------------------------------------------------------*/   
$(document).ready(function() {

    // create the view model
    var model = new ViewModel();

    // call the bind method for jquery UI setup
    model.bindSort();

    // binds ko attributes with the html
    ko.applyBindings(model);

});

and trying to do this in html,

<table data-bind="foreach: itemRows">
              <tr class="fruitList" data-bind="foreach: $data">
                  <td><img data-bind="attr: { src: $data }" /></td>
              </tr>
        </table>

I am not able to get the length of the array and also how can i break the loop once it creates 4 tds in the first and then create the second row.. Any suggestion ???

Update:

Below code doesnt seem to work when i use sortable,

    start: function (event, ui)
     {         
      startIndex = ui.item.index();
     },


     stop: function (event, ui) 
     {      
      var newIndex = ui.item.index();  

解决方案

UPDATE: Move to the bottom for the sortable version

Non-sortable version

I have created a jsfiddle which seems to meet your requirements before you edited and mentioned sorting: http://jsfiddle.net/fENSD/4/

What I did was create a computed observable that observes your items observable and returns a nested array in the shape that you want for your table rendering. This isn't the most efficient function, but with some work you could probably cut down on the number of arrays that get allocated (at the moment, 5 or so will be created for a 4x4 grid every time it is updated):

self.items = ko.observableArray(["images/1.jpg", "images/2.jpg", "images/3.jpg", "images/4.jpg", "images/5.jpg", "images/6.jpg"]);

self.itemRows = ko.computed(function () { //computes the rows dynamically based on items
    var rows = [];
    var count = 0;
    var items = self.items(); //get the item array
    var current = [];
    for(var i in items)
    {
        var item = items[i];
        current.push(item);
        count++;

        if (count == 4)
        {
            count = 0;
            rows.push(current);
            current = []; //next array
        }
    }

    if (current.length > 0)
    {
        rows.push(current);
    }

    return rows;
});

The table is then rendered like so:

<table data-bind="foreach: itemRows">
    <tr data-bind="foreach: $data">
        <td><img data-bind="attr: { src: $data }" /></td>
    </tr>
</table>

The JSFiddle includes an example of adding an item to the items observable and the table being updated to reflect that as well if you wanted to see that in action. There is also in the JSFiddle an example of one way you can get the length of the items array (data-bind="text: items().length").

Sortable version

It was a quite a change, but I managed to get the sorting working as well. Taking the example from the jquery ui website I got the following:

http://jsfiddle.net/fENSD/11/

It is very difficult to sort on tables, and so the jquery ui example actually used a list that had a defined width with each element taking up a certain width. This effectively creates a table. I assume that since you are using images that you can make them all exactly the same size.

To do this, I have some CSS like so:

#items { list-style-type: none; margin: 0; padding: 0; width: 200px; }
#items li { width: 48px; margin: 0px; padding: 0px; float: left; text-align: center; height: 48px; }

I then created a proper binding handler like so:

ko.bindingHandlers['sortable'] = {
    init: function (element, valueAccessor) {
        var $element = $(element);
        var observable = valueAccessor();
        var value = ko.utils.unwrapObservable(observable);
        $element.sortable({
            stop: function(event, ui) {
                var prev = ui.item.prev();
                var data = ko.dataFor(ui.item[0]);
                var index = 0;
                if (prev.length > 0) {
                    //not the first item
                    var prevData = ko.dataFor(prev[0]);
                    var index = value.indexOf(prevData) + 1;
                }
                var oldIndex = value.indexOf(data);
                value.splice(oldIndex, 1);
                value.splice(index, 0, data);
                observable.valueHasMutated();
            }
        });
    }
};

Whenever the sortable is updated, it modifies the observable array passed into the binding. Note: This is incredibly unrobust and needs to check to make sure that the passed value is actually an observable before telling it that its value has mutated.

The viewmodel looks like so:

function ViewModel() {
    var self = this;

    self.items = ko.observableArray(["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13"]);

    self.items.subscribe(function (value) {
        console.log(value); //this is so you can see that the array is indeed being re-sorted
    });

    self.add = function () {
        self.items.push("another thing");
    };
}

And to render:

<ul id="items" data-bind="sortable: items, foreach: items">
    <li><img data-bind="attr: { src: $data }" /></li>
</ul>

The limitations of this method are that if your items are different sizes, the order of the sortable will look a little different than what is actually represented in memory. However, providing that all of your elements are the same size, it should work just fine. The other issue is that this doesn't work well with duplicate items. However, to solve this it should be a simple matter of making each element an object containing a value (maybe even an observable value) instead of a plain old string.

这篇关于动态创建一行JS淘汰赛的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆