Solucionado (ver solução)

Importante

Você está vendo a versão anterior da nova experiência da Alura que estamos preparando para você. Em breve, ela ganha uma identidade visual novinha totalmente pensada em potencializar seus estudos!

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.