Solucionado (ver solução)
Solucionado
(ver solução)
10
respostas

Não aparece a tabela e seus dados no browse (Template dinâmico)

index.html

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Negociações</title>
    <link rel="stylesheet" href="css/bootstrap.css">
    <link rel="stylesheet" href="css/bootstrap-theme.css">
</head>

<body class="container">

    <h1 class="text-center">Negociações</h1>

    <div id="mensagemView"></div>

    <form class="form">

        <div class="form-group">
            <label for="data">Data</label>
            <input type="date" id="data" class="form-control" required autofocus/>        
        </div>    

        <div class="form-group">
            <label for="quantidade">Quantidade</label>
            <input type="number" min="1" step="1" id="quantidade" class="form-control" value="1" required/>
        </div>

        <div class="form-group">
            <label for="valor">Valor</label>
            <input id="valor" type="number" class="form-control"  min="0.01" step="0.01" value="0.0" required />
        </div>

        <button class="btn btn-primary" type="submit">Incluir</button>
    </form>

    <br>
    <br>

    <div id="negociacoesView"></div>

    <script scr="js/models/Negociacao.js"></script>
    <script scr="js/controllers/NegociacaoController.js"></script>
    <script scr="js/models/Negociacoes.js"></script>
    <script scr="js/views/NegociacoesView.js"></script>
    <script scr="js/views/MensagemView.js"></script>
    <script scr="js/app.js"></script>
</body>
</html>


class NegociacaoController {

    private _inputData: HTMLInputElement;
    private _inputQuantidade: HTMLInputElement;
    private _inputValor: HTMLInputElement;
    private _negociacoes = new Negociacoes();
    private _negociacoesView = new NegociacoesView('#negociacoesView');
    private _mensagemView = new MensagemView('#mensagemView');

    constructor() {
        this._inputData = <HTMLInputElement>document.querySelector('#data');
        this._inputQuantidade = <HTMLInputElement>document.querySelector('#quantidade');
        this._inputValor = <HTMLInputElement>document.querySelector('#valor');
        this._negociacoesView.update(this._negociacoes);
    }

    adiciona(event: Event) {

        event.preventDefault();

        const negociacao = new Negociacao(
            new Date(this._inputData.value.replace(/-/g, ',')), 
            parseInt(this._inputQuantidade.value),
            parseFloat(this._inputValor.value)
        );

        this._negociacoes.adiciona(negociacao);

        this._negociacoesView.update(this._negociacoes);
        this._mensagemView.update('Negociação adicionada com sucesso');

    }
}

class NegociacoesView {

private _elemento: Element;

constructor(seletor: string) {

    this._elemento = document.querySelector(seletor);
}

update(model: Negociacoes) {

    this._elemento.innerHTML = this.template(model);
}

template(model: Negociacoes): string {

    return `
    <table class="table table-hover table-bordered">
        <thead>
            <tr>
                <th>DATA</th>
                <th>QUANTIDADE</th>
                <th>VALOR</th>
                <th>VOLUME</th>
            </tr>
        </thead>

        <tbody>

        ${model.paraArray().map(negociacao => 
            `
                <tr>
                    <td>${negociacao.data.getDate()}/${negociacao.data.getMonth()+1}/${negociacao.data.getFullYear()}</td>
                    <td>${negociacao.quantidade}</td>
                    <td>${negociacao.valor}</td>
                    <td>${negociacao.volume}</td>
                </tr>                        
            `).join('')}            
        </tbody>

        <tfoot>
        </tfoot>
    </table>               
    `
}

}

class Negociacoes {

    private _negociacoes: Negociacao[] = [];

    adiciona(negociacao: Negociacao): void {

        this._negociacoes.push(negociacao);
    }

    paraArray(): Negociacao[] {

        return [].concat(this._negociacoes);
    }
}

class MensagemView {

private _elemento: Element;

constructor(seletor: string) {

    this._elemento = document.querySelector(seletor);
}

update(model: string) {

    this._elemento.innerHTML = this.template(model);
}

template(model: string): string {

    return `<p class="alert alert-info">${model}</p>`;
}

}

10 respostas

Fala ai Silvana, tudo bem? Está dando algum erro no console do navegador?

Fico no aguardo.

Bom dia Matheus, tudo bem e você ? Não exibe erro no console do navegador e começou a não mostrar mais a tabela quando foi incluída a div "negociacoesView" no index.html e incluída sua tratativa nos arquivos NegociacaoController.ts e NegociacoesView.ts

Fala Silvana, estou bem tambem, obrigada por perguntar.

Consegue compartilhar o código atual completo? Assim eu consigo simular o problema por aqui e analisá-lo com mais calma.

Pode compartilhar através do Github ou Google Drive (zipado).

Fico no aguardo.

Sivana, o problema está nas tags "script" do index.html. Você usou "scr" quando deveria ser "src".

Está assim:

    <script scr="js/models/Negociacao.js"></script>
    <script scr="js/controllers/NegociacaoController.js"></script>
    <script scr="js/models/Negociacoes.js"></script>
    <script scr="js/views/NegociacoesView.js"></script>
    <script scr="js/views/MensagemView.js"></script>
    <script scr="js/app.js"></script>

Altere para:

    <script src="js/models/Negociacao.js"></script>
    <script src="js/controllers/NegociacaoController.js"></script>
    <script src="js/models/Negociacoes.js"></script>
    <script src="js/views/NegociacoesView.js"></script>
    <script src="js/views/MensagemView.js"></script>
    <script src="js/app.js"></script>

Fala Silva, deu acesso negado para mim o projeto.

Mas, acredito que o problema seja por conta do scr no script com o Fred nos ajudou.

Caso não resolva, libera pra mim o projeto, assim eu consigo baixá-lo.

Abraços e bons estudos.

Matheus, não resolveu a correção para src. Por favor, verifique se está com acesso agora no projeto.

solução!

Oi Silvana. Também recebi o acesso ao seu código. Obrigado.

Realmente mudar de scr para src nas tags script não resolveu o problema.

Notei o seguinte erro ao executar npm start no terminal:

app/ts/controllers/NegociacaoController.ts(8,29): error TS2351: Cannot use 'new' with an expression whose type lacks a call or construct signature.
app/ts/views/MensagemView.ts(1,28): error TS2314: Generic type 'View<T>' requires 1 type argument(s).
app/ts/views/MensagemView.ts(5,14): error TS2339: Property '_elemento' does not exist on type 'MensagemView'.
10:27:29 AM - Compilation complete. Watching for file changes.

Notei que sua classe MensagemView estende a classe View sem especificar o tipo genérico, mas na declaração de View percebe-se que é uma classe genérica. Acredito que você estava fazendo o capitulo 4 sobre heranças e ainda não tinha terminado todos exercícios.

Para efeitos de testes do seu código, eu deixei a classe MensagemView sem estender View. Ficou assim:

class MensagemView {

    private _elemento: Element;

    update(model: string) {

        this._elemento.innerHTML = this.template(model);
    }

    template(model: string): string {

        return `<p class="alert alert-info">${model}</p>`;
    }
}

A compilação agora ocorre sem erro, mas ao tentar abrir o index.html no browser Chrome novamente, notei que a tabela de negociações não aparece. Então abri o console do browser e apareceu o seguinte erro:

Uncaught TypeError: Cannot set property 'innerHTML' of null
    at NegociacoesView.update (NegociacoesView.js:6)
    at new NegociacaoController (NegociacaoController.js:9)
    at app.js:1

Quebrei a cabeça nessa parte porque parece tudo certo com o restante do código typscript. Até comparei os arquivos ts seu e meu usando o programa WinMerge. Exceto pelo espaçamento entre linhas, nossos códigos estavam iguais.

Então, com browser aberto, cliquei com botão direito do mouse na área onde deveria aparecer a tabela e escolhi a opção de inspecionar a página. Notei que a tag div negociacoesView estava assim:

<div id="negociacoesview">

    <script src="js/models/Negociacao.js"></script>
    <script src="js/controllers/NegociacaoController.js"></script>
    <script src="js/models/Negociacoes.js"></script>
    <script src="js/views/View.js"></script>
    <script src="js/views/NegociacoesView.js"></script>
    <script src="js/views/MensagemView.js"></script>
    <script src="js/app.js"></script>

</div id="negociacoesview">

Essa formação da tag div dava erro na linha this._elemento.innerHTML = this.template(model); na classe NegociacoesView. O erro informado acima: Uncaught TypeError: Cannot set property 'innerHTML' of null.

Porém, você escreveu corretamente assim no arquivo HTML (o código abaixo já está com src corrigido):

    <div id="negociacoesView"></div>

    <script src="js/models/Negociacao.js"></script>
    <script src="js/controllers/NegociacaoController.js"></script>
    <script src="js/models/Negociacoes.js"></script>
    <script src="js/views/View.js"></script>
    <script src="js/views/NegociacoesView.js"></script>
    <script src="js/views/MensagemView.js"></script>
    <script src="js/app.js"></script>

Então resolvi comparar o index.html seu e meu usando o WinMerge e deu um diferença no espaçamento entre div e id, ou seja, algum caractere entre esses dois termos eram diferentes entre nossos códigos. Removi o caractere no seu código e acrescentei o espaço. Dessa forma a tabela apareceu no browser.

Talvez você copiou parte do trecho HTML de um local para o seu arquivo e veio junto um caractere especial. Se for isso mesmo, é bom usar um programa que remove caractere especial ou usar um editor como intermediário. Em alguns editores, é possível colar um conteúdo e o próprio editor remove os esses caracteres. Dessa forma só copiar o texto do editor que estará correto.

Aqui não tem como inserir prints de tela, senão postava a comparação do WinMerge, mas abaixo eu mostro onde estava o caractere especial:

<div[CARACTERE_ESPECIAL_ESTAVA_AQUI]id="negociacoesView">

Veja se com essa alteração, além da correção de src da tag script, resolve o problema.

Boa tarde Fred, deu certo retirando o caractere especial. Muito obrigada !

Fala Fred e Silvana, muito bom gente, obrigada pela ajuda Fred.

Silvana, sempre que precisar não deixe de criar suas dúvidas.

Abraços e bons estudos galera.

Quer mergulhar em tecnologia e aprendizagem?

Receba a newsletter que o nosso CEO escreve pessoalmente, com insights do mercado de trabalho, ciência e desenvolvimento de software