带打字稿和HTML的动态表

时间:2018-12-20 11:29:50

标签: html typescript dynamic

目前,我会使用打字稿和HTML进行小练习。这包括建立一个可以在其中添加,编辑和删除项目的表格。我现在挂在要编辑或删除项目的地方。

我只是通过该函数将HTML代码添加到网站。现在,我想将对象赋予onclick函数。因此,当函数被触发时,我直接拥有相应的对象。 然而,目前我的IDE表示从HTML中的toTableString函数调用函数deleteUser时:Unresolved variable or type user

代码:

interface IUser {
    firstName: string,
    lastName: string,
    userName: string,
    password: string
}

class User implements IUser {
    firstName: string;
    lastName: string;
    password: string;
    userName: string;

    constructor(firstName: string, lastName: string, password: string, userName: string) {
        this.firstName = firstName;
        this.lastName = lastName;
        this.password = password;
        this.userName = userName;
    }
}

let list: Array<IUser> = []

function createUser() {

    const firstNameInput = (<HTMLInputElement>document.getElementById('first-name')).value;
    const lastNameInput = (<HTMLInputElement>document.getElementById('last-name')).value;
    const userNameInput = (<HTMLInputElement>document.getElementById('user-name')).value;
    const passwordInput = (<HTMLInputElement>document.getElementById('password')).value;

    list.push(new User(firstNameInput, lastNameInput, passwordInput, userNameInput));

    (<HTMLFormElement>document.getElementById("createUserForm")).reset();

    updateTable()
}

function updateTable() {

    let tableString: string = "<table class=\"table\"><thead><tr><th scope=\"col\">#</th><th scope=\"col\">First Name</th><th scope=\"col\">Last Name</th><th scope=\"col\">User Name</th></tr></thead><tbody>"
    for (let _i = 0; _i < list.length; _i++) {
        let user: IUser = list[_i];

        tableString = tableString + toTableString(_i, user);
    }

    tableString = tableString + "</tbody></table>";

    (<HTMLSpanElement>document.getElementById("userTable")).innerHTML = tableString;
}

function toTableString(row: number, user: IUser): string {
    return "<tr><th scope=\"row\">" + (row + 1) + "</th><td>" + user.firstName + "</td><td>" + user.lastName + "</td><td>" + user.lastName + "</td><td><span class=\"glyphicon glyphicon-pencil\"></span></td><td><span  onclick='deleteUser(user)' class=\"glyphicon glyphicon-trash\"></span></td></tr>";
}

function deleteUser(user: IUser) {
    alert(user.userName)
}

function editUser(user: IUser) {

}

结果应该是if函数

function deleteUser (user: IUser) {
    alert (user.userName)
}

被调用,对应的名称就是输出。

感谢您的帮助,如果您有改进的一般建议,欢迎您写信

2 个答案:

答案 0 :(得分:0)

这将无法正常工作。 HTML中直接存在的任何变量都只会在该上下文中解析。 HTML无法访问user中的toTableString参数。

通常,在使用DOM时,您可能需要解析它,然后将事件附加到代码中。还有大量的模板/绑定库可以帮助您解决问题。

可以简化用户:

class User implements IUser
{
    constructor(
        public firstName: string,
        public lastName: string,
        public password: string,
        public userName: string
    ) { }
}

我在这里解析Table框架,然后向其中添加行并直接替换旧表(如果该表已经存在,则无需重新创建它,您只需清除行并添加新行):

function updateTable()
{
    const tableString: string = /*html*/`
        <table class="table">
            <thead>
                <tr>
                    <th scope="col">#</th>
                    <th scope="col">First Name</th>
                    <th scope="col">Last Name</th>
                    <th scope="col">User Name</th>
                </tr>
            </thead>
            <tbody></tbody>
        </table>`;

    const parser = new DOMParser();
    /** Parses an element and assigns the correct type. */
    const parse = <T extends HTMLElement>(str: string) =>
        <T>parser.parseFromString(str, 'text/html').documentElement;

    const table = parse<HTMLTableElement>(tableString);

    list.forEach((user, index) =>
    {
        const rowString = toTableString(index, user);
        const row = parse<HTMLTableRowElement>(rowString);

        // Adding handler to DOM here (identified via attribute).
        row.querySelector('[data-delete-button]')!.addEventListener('click', () => deleteUser(user));

        table.tBodies[0].appendChild(row);
    });

    const existingTable = document.getElementById("userTable");
    existingTable.parentElement.replaceChild(table, existingTable);
}

function toTableString(row: number, user: IUser): string
{
    return /*html*/`<tr>
        <th scope="row">${row + 1}</th>
        <td>${user.firstName}</td>
        <td>${user.lastName}</td>
        <td>${user.lastName}</td>
        <td><span class="glyphicon glyphicon-pencil"></span></td>
        <td><span class="glyphicon glyphicon-trash" data-delete-button></span></td>
    </tr>`;
}

使用模板文字(以反引号结尾的字符串)可以使换行,并且可以通过${...}插入数据。您也可以在编辑器中正确突出显示它,例如:

vs code

但是请注意,您应该从不以这种方式从任何包含用户输入的内容中构造HTML,而无需先对其进行正确的转义。

答案 1 :(得分:0)

我尝试了更多,得出了现在对我有用的解决方案。

function addUserToTable(user: IUser, index: number) {
    // Get a reference to the table
    let table = <HTMLTableElement>document.getElementById("userTable");


    let newRow = table.tBodies[0].insertRow(-1);

    let number = newRow.insertCell(0);

    let firstName = newRow.insertCell(1);

    let lastName = newRow.insertCell(2);

    let userName = newRow.insertCell(3);

    let edit = newRow.insertCell(4);

    let del = newRow.insertCell(5);
    // Append a text node to the cell
    number.appendChild(document.createTextNode("" + index));
    firstName.appendChild(document.createTextNode(user.firstName));
    lastName.appendChild(document.createTextNode(user.lastName));
    userName.appendChild(document.createTextNode(user.userName));


    let editSpan = document.createElement("span");
    editSpan.setAttribute("class", "glyphicon glyphicon-pencil");
    editSpan.setAttribute("data-toggle", "modal");
    editSpan.setAttribute("data-target", "#updateUserModal");

    editSpan.addEventListener('click', function () {
        editUser(user);
    });

    edit.appendChild(editSpan);

    let delSpan = document.createElement("span");
    delSpan.setAttribute("class", "glyphicon glyphicon-trash");


    delSpan.addEventListener('click', function () {
        deleteUser(user);
    });

    del.appendChild(delSpan);
}

function updateTable() {
    let table = <HTMLTableElement>document.getElementById("userTable");
    var new_tbody = document.createElement('tbody');
    table.replaceChild(new_tbody, table.tBodies[0])

    list.forEach((user, index) => {
        addUserToTable(user, index + 1)
    })
}

使用DomParser,我还有其他问题,即在执行过程中找不到任何方法。编译时一切正常