Api Web ASP.NET + KnockoutJs + MVC4 - Ligando-o

9

Estou começando um novo projeto, e estou ansioso para usar o KnockoutJS + Web Api que é novo para mim, eu tenho um bom entendimento do Web Api, mas o Knockout é difícil de entender no momento.

Esta é a minha ideia inicial de como quero que meu aplicativo funcione:

  • Eu tenho um controlador MVC padrão, como LeadsController
  • LeadsController tem um Action chamado ListLeads , mas, na verdade, ele não retorna nenhum dado, mas apenas retorna uma exibição com um modelo para exibir dados do Nocaute.
  • A exibição ListLeads chama meu controlador da API LeadsApiController via ajax para obter uma lista de leads a serem exibidos
  • Os dados de leads são então mapeados para um ViewModel do KnockoutJs (não quero replicar meus modelos de visualização do lado do servidor para modelos de exibição JavaScript)
  • Eu quero usar arquivos JavaScript externos o máximo possível, em vez de inchar minha página HTML cheia de JavaScript.

Eu tenho visto muitos exemplos, mas a maioria deles retorna alguns dados iniciais no primeiro carregamento da página, ao invés de uma chamada ajax.

Então, minha pergunta é: como criar meu viewModel do JavaScript para o Knockout quando recuperado do ajax, onde o URL do ajax é criado usando Url.Content() .

Além disso, e se eu precisar de valores computados adicionais neste ViewModel, como eu estenderei o modelo de visualização mapeado do lado do servidor?

Se eu não tiver me explicado bem, me avise do que você não tem certeza e tentarei atualizar minha pergunta para ser mais explícito.

    
por Paul Hinett 17.08.2012 в 02:48
fonte

2 respostas

4

Eu acho que seu design é uma boa ideia. Na verdade, estou desenvolvendo um aplicativo usando exatamente esse design agora!

Você não precisa incorporar os dados iniciais em sua página. Em vez disso, quando sua página for carregada, crie um modelo de exibição vazio, chame ko.applyBindings e inicie uma chamada AJAX que preencherá o modelo de exibição quando ele for concluído:

$(function () {
    var viewModel = {
        leads: ko.observableArray([]) // empty array for now
    };

    ko.applyBindings(viewModel);

    $.getJSON("/api/Leads", function (data) {
        var newLeads = ko.mapping.fromJS(data)(); // convert to view model objects
        viewModel.leads(newLeads); // replace the empty array with a populated one
    });
});

Você desejará colocar uma mensagem "Carregando" em algum lugar da sua página até que a chamada AJAX seja concluída.

Para gerar o URL "/ api / Leads", use Url.RouteUrl :

<script>
    var apiUrl = '@Url.RouteUrl("DefaultApi", new { httproute = "", controller = "Leads" })';
</script>

(Supondo que sua rota de API configurada em Global.asax ou App_Start \ RouteConfig.cs seja denominada "DefaultApi".)

O plugin de mapeamento de knockout é usado acima para converter o resultado JSON do AJAX em um modelo de visualização de eliminação. Por padrão, o modelo de visualização gerado terá uma propriedade observável para cada propriedade no JSON. Para personalizar isso, como adicionar outras propriedades computadas, use o "callback" de criação do plug-in de mapeamento de eliminação.

Após chegar tão longe em meu aplicativo, descobri que queria mais metadados dos modelos de exibição do lado do servidor disponíveis para o código do lado do cliente, como quais propriedades são necessárias e quais são as validações em cada propriedade. No mapeamento de eliminação "criar" retornos de chamada, eu queria essas informações para gerar automaticamente propriedades adicionais e observáveis computados nos modelos de exibição. Então, no lado do servidor, usei algumas classes de framework MVC e reflexão para inspecionar os modelos de visão e gerar alguns meta-dados como JavaScript, que fica embutido nas visualizações relevantes. No lado do cliente, tenho arquivos JavaScript externos que conectam os retornos de chamada do mapeamento de eliminação e geram modelos de exibição de acordo com os metadados fornecidos na página. Meu conselho é começar escrevendo as personalizações do modelo de visualização eliminável e outro JavaScript manualmente em cada visualização e, ao refatorar, mover funções JavaScript genéricas para arquivos externos. Cada exibição deve acabar com apenas o JavaScript mínimo que é específico para essa exibição, ponto no qual você pode considerar escrever algum C # para gerar esse JavaScript a partir das anotações do modelo de exibição do lado do servidor.

    
por Joe Daley 17.08.2012 / 14:09
fonte
1

Para o problema de url, adicione isso em seu _Layout.cshtml em um lugar onde esteja antes dos arquivos que o usarão:

<script>
    window._appRootUrl = '@Url.Content("~/")';
</script>

Depois, você pode usar o window._appRootUrl para compor urls com concatenação de strings ou com a ajuda de uma biblioteca javascript como o URI.js.

Quanto aos valores computados adicionais, você pode querer usar um nocaute computável observável. Se isso não for possível ou se você preferir fazê-lo em .Net, você deve ser capaz de criar uma propriedade apenas com um getter, mas isso não será atualizado quando você atualizar outras propriedades no cliente, se depender delas.

    
por kendaleiv 17.08.2012 / 04:43
fonte