代码之家  ›  专栏  ›  技术社区  ›  JoshuaBr

以动态方式访问动态创建的变量

  •  3
  • JoshuaBr  · 技术社区  · 11 年前

    这可能需要一些解释,所以请耐心等待。

    我试图创建X个表,每个表的长度(列)都不同,每个表有4行,X和Y由用户决定。这部分我已经解决了。

    问题是,每个表中的每个单元格都必须包含自己的文本框,其中包含从数据库派生的数字。如果用户更改了文本框中的数字,则更改必须反映在数据库中。

    考虑到表的数量和长度是未知的,我不能提前设置文本框的名称,必须动态设置。

    我偶然发现了以下代码:

    var pageNumber = 1;
    eval("var text" + pageNumber + "=123;");
    alert(text1);
    //alert shows '123'
    

    我相信这(经过修改)将允许我为每个文本框动态创建一个唯一的名称。我遇到的问题是,由于我不知道它叫什么(在创建表之后),我如何访问这个新的文本框?

    我计划使用一个3d数组来保存我希望在表中每个单元格中显示的数字,并计划使用这个数组来命名单元格。

    作为一个例子,数组可以是array[i][j][k],假设i=1,j=2,k=3,它将保持数字8。 动态创建的文本框名称如下所示: 文本框123

    如何将数组中的单元格(包含8)与新的文本框相关联,然后在我不知道其名称的情况下提前检索并存储新值?

    我的想法是,我该如何写这样的东西

     <input type="text" name="textBox123" value=array[i][j][k]> 
    

    到html?

    再说一遍,也许我想得太多了,有更好的方法。如果是这样,请告诉我。

    4 回复  |  直到 11 年前
        1
  •  1
  •   kol    11 年前

    HTML格式:

    <div id="tables"></div>
    

    JavaScript语言:

    var tables = [
            // Table #1
            [
                [111, 112, 113], // Row #1
                [121, 122, 123]  // Row #2
            ],
            // Table #2
            [
                [211, 212, 213, 214], // Row #1
                [221, 222, 223, 224], // Row #2
                [231, 232, 233, 234]  // Row #3
            ],
            // Table #3 (empty!)
            []
        ],
        nr, nc, i, j, k,
        name, value, textBox, cell, row, table,
        $tables = $("#tables");
    
    for (i = 0; i < tables.length; ++i) {
        nr = tables[i].length;
        nc = nr > 0 ? tables[i][0].length : 0;
        table = "<table>";
        for (j = 0; j < nr; ++j) {
            row = "<tr>";
            for (k = 0; k < nc; ++k) {
                name = "textBox" + (i + 1) + (j + 1) + (k + 1);
                value = tables[i][j][k];
                textBox = "<input type='text' name='" + name + "' value='" + value + "'>";
                cell = "<td>" + textBox + "</td>";
                row += cell;
            }
            row += "</tr>\n";
            table += row;
        }
        table += "</table>\n";
        $tables.append(table);
    }
    

    请参阅 jsfiddle 。第三个空表将作为空表插入 table 标签,但这不是必须的。

    我想提到的是,由于您需要将这些表连接到数据库,因此一个优雅的解决方案是使用 客户端MVC框架 喜欢 Backbone.js . Here 你会发现一本很好的入门书。这个 View 可以使用与上面类似的代码 render 桌子。这个 tables 数组可以存储在 Collection .

        2
  •  1
  •   jfriend00    11 年前

    您不必用索引预先标记表中的每个单元格,因为您可以根据需要根据DOM层次结构来计算它。

    如果表中有一个任意单元格,则可以获得该单元格在表中的行号和列号,如下所示 cell 传递给该函数的可以是 td 对象或其任何后代(例如 <input> 表中的标签):

    // Pass any td object or descendant of a td object in a <table> and it will return
    // an object with {row: x, col: y}
    // or return null if the cell passed wasn't inside a <tr> and <td>
    function findRowColInTable(cell) {
    
        function findParent(obj, parentTagName) {
            parentTagName = parentTagName.toUpperCase();
            while (obj && obj.tagName != parentTagName) {
                obj = obj.parentNode;
            }
            return obj;
        }
    
        findChildCnt(obj) {
            var cnt = 0;
            while (obj = obj.prevSibling) {
                ++cnt;
            }
            return cnt;
        }
    
        var td, tr, col, row;
    
        // get table cell
        td = findParent(cell, "TD");
        if (td) {
            col = findChildCnt(td);
            tr = findParent(td, "TR");
            if (tr) {
                row = findChildCnt(tr);
                return {row: row, col: col};
            }
        }
        return null;
    }
    

    仅供参考,这在jQuery中要容易得多,您可以使用 .closest(tag) .index() 找到合适的父母并获得本地兄弟姐妹的数量,但我为您提供了一个纯javascript版本。

        3
  •  0
  •   Community CDub    7 年前

    实际上,您可以在窗体上执行数组。拿 my old answer for example ,您可以使用这样的命名方案在表单输入中创建数组。在后端,您可以将它们作为数组(假设为PHP)。

    如果您是通过JS获取值,那么您可以将其作为基础 this answer ,它利用命名方案,获取表单值并将它们转换为JS对象和数组,类似于PHP在后端接收它们的方式。基本上,它贯穿表单并获取表单值。它的一部分是jQuery,但如果您不想合并整个库,可以从jQuery中获取源代码。

        4
  •  0
  •   Yudho Ahmad Diponegoro    11 年前

    您可以使用javascript面向对象的概念

    每个表都有相应的表对象,其行和单元格也是如此。 通过这种技术,每个对象在真实的DOM中都有其“元素”。

    诀窍是,将事件侦听器(例如,当用户在文本框中键入某些内容时)附加到对象,这样该事件侦听器将只对应于该特定单元格,而不会干扰其他列、行和表中的其他单元格。

    以下是可能的解决方案。很抱歉我的jQuery重度依赖。我只是不知道如何用document.createElement()创建元素(我的坏知识),当然可以用纯javascript实现(没有jQuery)来更改它们。

         values=new Array();
         function Cell(id,values_row){ //Cell class
            this.id=id;
            this.element=$("<td></td>");           
            this.textbox=$("<input type='text' name='"+this.id+"' id='"+this.id+"'></input>");
            values_row[id]="" //initiate default value == ""
                //here is the trick
            this.textbox.change(function(){ //you can use onchange if you dont like jQuery
                values_row[id]=$(this).val();             
                //other tasks need to be done when user changes the value of a textbox (typing)
            });
            this.textbox.appendTo(this.element);    
        }
        function Row(id,number_of_columns,values_table){ //Row class
            this.id=id
            this.element=$("<tr></tr>")                
            values_table[id]=new Array(); //make array "values" becomes 3D              
            for(var col =0;col<number_of_columns;col++){
                var the_cell=new Cell(col,values_table[col]);
                the_cell.element.appendTo(this.element);
            }
        }
        function Table(id,number_of_columns){ //Table class
            this.id=id
            this.element=$("<table></table>")
            values[id]=new Array();  //make array "values" becomes 2D                     
            for(var row=0;row<4;row++){
                var the_row=new Row(row,number_of_columns,values[id]);
                the_row.element.appendTo(this.element)                       
            }
        }
        // creating the tables
        for(var t=0;t<number_of_tables_needed;t++){
            the_table=new Table(t,number_of_column_for_this_table);
            the_table.element.appendTo(table_container_element);
        }
        //do input some text into some cells then
        alert(values)
    

    警报将显示一个三维数组,其中包含按表号、行号以及精确指向单元格的列进行索引的所有单元格的值。单元格值的默认值为“”

    使用此技术,您不需要为刚输入值的相应单元格找到正确的数组元素。相反,在DOM中创建元素之前附加事件侦听器。这是解决问题的一种面向对象的方法。

    当用户每次输入时都需要找到相应的数组单元时,这种解决方案的算法复杂度不是O(n^3),而是在对象初始化过程中花费更多的时间,但之后,它是O(1)。