【问题标题】:Fill html-table data with jquery fails Uncaught ReferenceError用 jquery 填充 html 表数据失败 Uncaught ReferenceError
【发布时间】:2019-04-17 10:56:50
【问题描述】:

我想在Angular 中使用jquery 根据我的数据输入创建一个表。我是jquery 的新手,所以这可能是我忘记的一些愚蠢的事情,但我不能说它是什么。

可悲的是,当我执行 ng serve 时,什么都没有发生,只是一个空白页。

我得到以下代码:

HTML

<body onLoad="createHeaders('#dataTable')">
    <table #dataTable >
    </table>
</body>

TS

import { Component, OnInit } from '@angular/core';
import { MOCKUP } from '../Table';
import * as $ from "jquery";

@Component({
  selector: 'app-tabular',
  templateUrl: './tabular.component.html',
  styleUrls: ['./tabular.component.css']
})
export class TabularComponent implements OnInit {


  constructor() { }

  ngOnInit() {

  }

  //this is where i want to work in the future, lets just forget about that for the moment
  buildHTMLTableCodeFromTree(selector) {
    //var header = this.createHeaders(selector, MOCKUP.Head);
    $(selector).append("<td>test</td>");
  }

  createHeaders(selector) {
    var headObject = MOCKUP.Head;

    console.log("Er ist in der Methode!");

    var value;
    var colspan;
    var entry = "";

    for (var j = 0; j < headObject.length; j++) {
      entry = entry + "<tr>";
      for (var i = 0; i < headObject[j].length; i++) {
        value = headObject[j][i].value;
        colspan = headObject[j][i].colspan;
        entry = entry + "<th colSpan='" + colspan + "'>" + value + "</th>";
      }
      entry = entry + "</tr>";
    }
    $("dataTable").append(entry);
  }

}

表头模型:

export const MOCKUP = {
    "Table": "tab1",
    "Head": [
        [
            {
                "value": "",
                "colspan": 1,
            },
            {
                "value": "2018",
                "colspan": 2
            },
            {
                "value": "2019",
                "colspan": 6
            }
        ],
        [
            {
                "value": "",
                "colspan": 1,
            },
            {
                "value": "December",
                "colspan": 2
            },
            {
                "value": "January",
                "colspan": 2
            },
            {
                "value": "February",
                "colspan": 2
            },
            {
                "value": "March",
                "colspan": 2
            }
        ],
        [
            {
                "value": "",
                "colspan": 1,
            },
            {
                "value": "Foo",
                "colspan": 1,
            },
            {
                "value": "Boo",
                "colspan": 1,
            },
            {
                "value": "Foo",
                "colspan": 1,
            },
            {
                "value": "Boo",
                "colspan": 1,
            },
            {
                "value": "Foo",
                "colspan": 1,
            },
            {
                "value": "Boo",
                "colspan": 1,
            },
            {
                "value": "Foo",
                "colspan": 1,
            },
            {
                "value": "Boo",
                "colspan": 1,
            }
        ]
    ],
    "Body": [
        [
            {   
                "value": "Total",
                "entryID": -1
            },
            {   
                "value": "10",
                "entryID": 33
            },
            {   
                "value": "24",
                "entryID": 34
            },
            {   
                "value": "66",
                "entryID": 35
            },
            {   
                "value": "0",
                "entryID": 36
            },
            {   
                "value": "23",
                "entryID": 37
            },
            {   
                "value": "24",
                "entryID": 38
            },
            {   
                "value": "21",
                "entryID": 39
            },
            {   
                "value": "10",
                "entryID": 40
            }
        ],
        [
            {   
                "value": "Row1",
                "entryID": -1
            },
            {   
                "value": "10",
                "entryID": 1
            },
            {   
                "value": "12",
                "entryID": 2
            },
            {   
                "value": "0",
                "entryID": 3
            },
            {   
                "value": "0",
                "entryID": 4
            },
            {   
                "value": "0",
                "entryID": 5
            },
            {   
                "value": "0",
                "entryID": 6
            },
            {   
                "value": "0",
                "entryID": 7
            },
            {   
                "value": "0",
                "entryID": 8
            }
        ]
    ]
}

我希望它是一个三行标题(年、月和我的HEAD-array 的最后一个值中的最后一行)。我已经尝试按照

我也尝试像here 描述的那样做(所以使用$("#dataTable").append(entry);,但这不会改变结果。

编辑:确实有错误,不是在执行ng serve的命令提示符中,而是在Chrome控制台中:

未捕获的 ReferenceError:未定义 createHeaders 在加载时 (localhost/:13)

显然他在执行 HTML 代码时没有实例化该方法。

编辑:我为什么要尝试使用 jquery? 注意:这对于问题本身可能不是必需的,它只是作为解释

这是我的数据示例:

以及所需的输出:

现在输出必须是可编辑的,并且这些编辑应该保存在我的数据库中(点击按钮时,这就是我在模型中保存 entryID 的原因)。

对于来自后端->前端的通信,我考虑了原始数据的上述格式(这就是我保存 entryID 的原因):

【问题讨论】:

  • 为什么要使用jquery在angular中操作DOM?
  • @L.A 我编辑了我的问题并试图解释我要这样做的原因和原因。如果您还有其他可能性,请随时告诉我:)(我知道您不应该在问题中提出这些问题,但我仍然愿意接受其他想法)

标签: jquery html angular typescript


【解决方案1】:

但是,如果您想要真正快速的东西,最好不要使用 jQuery,并尽可能多地重用您生成的对象。

&lt;table id="dataTable"&gt;&lt;/table&gt;

const MOCKUP = [{
  type: 'thead',
  children: [{
    type: 'tr',
    dataset: {id: 1},
    children: [
      {type: 'th', textContent: '', colSpan: 1, contentEditable: true},
      {type: 'th', textContent: '2018', colSpan: 2, contentEditable: true},
      {type: 'th', textContent: '2019', colSpan: 6, contentEditable: true}
    ]
  }, {
    type: 'tr',
    dataset: {id: 2},
    children: [
      {type: 'th', textContent: '', colSpan: 1, contentEditable: true},
      {type: 'th', textContent: 'December', colSpan: 2, contentEditable: true},
      {type: 'th', textContent: 'January', colSpan: 2, contentEditable: true},
      {type: 'th', textContent: 'February', colSpan: 2, contentEditable: true},
      {type: 'th', textContent: 'March', colSpan: 2, contentEditable: true}
    ]
  }, {
    type: 'tr',
    dataset: {id: 3},
    children: [
      {type: 'th', textContent: '', colSpan: 1, contentEditable: true},
      {type: 'th', textContent: 'Foo', colSpan: 1, contentEditable: true},
      {type: 'th', textContent: 'Boo', colSpan: 1, contentEditable: true},
      {type: 'th', textContent: 'Foo', colSpan: 1, contentEditable: true},
      {type: 'th', textContent: 'Boo', colSpan: 1, contentEditable: true},
      {type: 'th', textContent: 'Foo', colSpan: 1, contentEditable: true},
      {type: 'th', textContent: 'Boo', colSpan: 1, contentEditable: true},
      {type: 'th', textContent: 'Foo', colSpan: 1, contentEditable: true},
      {type: 'th', textContent: 'Boo', colSpan: 1, contentEditable: true}
    ]
  }]
}];

const cache = {};

function assign(destination, source) {
  for (const key in source) {
    if (source.hasOwnProperty(key)) {
      const value = source[key];

      if (typeof value === 'object') {
        assign(destination[key], value);
      } else if (null != destination) {
        destination[key] = value;
      }
    }
  }

  return destination;
}

function get(data, pathStr) {
  const path = pathStr.split('.');
  let i = path.length;

  while (--i) {
    data = data[path[i]];
  }

  return data;
}

function disassemble(target) {
  let element;

  while ((element = target.lastElementChild)) {
    target.removeChild(element);
    disassemble(element);

    const type = element.tagName.toLowerCase();
    const c = cache[type] || (cache[type] = []);

    c.push(element);
  }
}

function assemble(target, path, data = []) {
  const fragment = document.createDocumentFragment();

  data.forEach(({type, children, ...config}, i) => {
    const element = assign(cache[type] && cache[type].pop() || document.createElement(type), config);
    const newPath = `.${i}${path}`;

    element.dataset.path = newPath;
    assemble(element, `.children${newPath}`, children);

    fragment.appendChild(element);
  });

  target.appendChild(fragment);
}

function render(target, data) {
  window.requestAnimationFrame(() => {
    disassemble(target);
    assemble(target, '', data);
  });
}

const table = document.getElementById('dataTable');

table.addEventListener('input', ({target: {dataset, textContent, parentElement}}) => {
  // use this to update local data
  get(MOCKUP, dataset.path).textContent = textContent;

  // easy access to row id (dataset values can only be strings)
  parentElement.dataset.id

  // raw dataset with all types and deep objects intact
  get(MOCKUP, parentElement.dataset.path).dataset.id
});

render(table, MOCKUP);

不如 React 快,但非常接近。

【讨论】:

  • 所以我的想法是,如果我只是生成一个格式化为 HTML 表的字符串对象并传递它,这可能会起作用,但遗憾的是,当条目更改时,我无法确定哪个条目是在我的数据库中更新它,还是我遗漏了什么?但是当我写这篇评论时,我发现我的解决方案也没有向我提供这个......
  • @Rüdiger 我稍微扩展了示例。现在可以编辑表格,并且可以轻松获取 id 或您可能需要的任何基础数据。
【解决方案2】:

我对 Angular 不是很熟悉,但是这段代码对我来说似乎很陌生

<table #dataTable >
</table>

也许你的意思

<table id="dataTable">
</table>

【讨论】:

  • 感谢解答,发现错误!我更新了我的描述
猜你喜欢
  • 1970-01-01
  • 2011-11-04
  • 2014-07-03
  • 2014-11-05
  • 2018-04-13
  • 1970-01-01
  • 1970-01-01
  • 2018-06-15
  • 2018-12-18
相关资源
最近更新 更多