9

Sto iniziando un nuovo progetto, e mi piace usare il KnockoutJS + Web Api che sono nuovo per me, ho una buona conoscenza del Web Api, ma Knockout è difficile da capire in questo momento.ASP.Net Web Api + KnockoutJs + MVC4 - Legare insieme

Questo è il mio pensiero iniziale di come voglio che la mia app per lavorare:

  • Ho un controller standard MVC come LeadsController
  • LeadsController ha un Action chiamato ListLeads, questo in realtà non restituire alcun i dati però, ma restituisce solo una vista con un modello per visualizzare i dati da Knockout.
  • La vista ListLeads chiama il mio controller api LeadsApiController tramite la tecnologia AJAX per ottenere una lista di contatti per visualizzare
  • I dati cavi è poi associati a un KnockoutJs ViewModel (Non voglio replicare mio punto di vista i modelli dal lato server in JavaScript visualizza modelli)
  • Desidero utilizzare i file JavaScript esterni il più possibile anziché gonfiare la mia pagina HTML piena di JavaScript.

Ho visto molti esempi ma la maggior parte di essi restituisce alcuni dati iniziali sul caricamento della prima pagina, piuttosto che tramite una chiamata ajax.

Quindi la mia domanda è: come creare il mio JavaScript viewModel per Knockout quando recuperato da ajax, dove viene creato l'url ajax utilizzando Url.Content().

Inoltre, se avessi bisogno di ulteriori valori calcolati su questo ViewModel, come estenderò il modello di visualizzazione mappato dal lato server.

Se non mi sono spiegato bene, per favore fammi sapere di cosa non sei sicuro e cercherò di aggiornare la mia domanda per essere più esplicita.

risposta

4

Penso che il tuo design sia una buona idea. In effetti, sto sviluppando un'applicazione che usa esattamente questo design in questo momento!

Non è necessario incorporare i dati iniziali nella pagina. Invece, quando il caricamento della pagina, creare una vista modello di vuoto, chiamare ko.applyBindings, quindi avviare una chiamata AJAX che popolare il modello di vista quando completa:

$(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 
    }); 
}); 

Avrai voglia di mettere un messaggio "Loading" da qualche parte sulla tua pagina fino al completamento della chiamata AJAX.

per generare il "/ api/Leads" URL, utilizzare Url.RouteUrl: (. Questo supponendo l'itinerario API configurata in Global.asax o App_Start \ RouteConfig.cs si chiama "DefaultApi")

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

Il plug-in di mappatura a eliminazione diretta viene utilizzato in precedenza per convertire il risultato JSON AJAX in un modello di visualizzazione a eliminazione diretta. Per impostazione predefinita, il modello di vista generato avrà una proprietà osservabile per ogni proprietà nel JSON. Per personalizzare questo, come aggiungere ulteriori proprietà calcolate, utilizzare il plug-in del mapping di knockout "create" callback.

Dopo essermi spinto così lontano nella mia applicazione, ho scoperto che volevo più metadati dai modelli di vista lato server disponibili per il codice lato client, quali le proprietà richieste e le convalide su ogni proprietà. Nella mappatura a eliminazione diretta "crea" i callback, volevo queste informazioni per generare automaticamente proprietà aggiuntive e osservabili calcolati nei modelli di visualizzazione. Quindi, sul lato server, ho utilizzato alcune classi e riflessioni del framework MVC per ispezionare i modelli di visualizzazione e generare alcuni metadati come JavaScript che vengono incorporati nelle viste pertinenti. Sul lato client, ho i file JavaScript esterni che collegano i callback di knockout mapping e generano modelli di visualizzazione in base ai meta-dati forniti nella pagina. Il mio consiglio è di iniziare scrivendo le personalizzazioni del modello di visualizzazione ad eliminazione diretta e altri JavaScript a mano in ogni vista, quindi come refactor, sposta le funzioni JavaScript generiche in file esterni. Ogni vista dovrebbe finire con solo il minimo JavaScript che è specifico per quella vista, a quel punto si può considerare di scrivere un C# per generare quel JavaScript dalle annotazioni del modello di vista lato server.

+0

Ciao Joe. Il tuo approccio è assolutamente corretto e molti tutorial/blog che ho visto hanno una soluzione simile. Ho valutato questo approccio per una grande applicazione web che stiamo iniziando. Il mio problema è scrivere molto di JS che ritengo sia difficile da gestire. Inoltre, che senso ha utilizzare i controller MVC e WebAPI e perché utilizzare un controller MVC per passare una vista vuota? sembra come la sua creazione di doppiezza. – Yashvit

+0

MCV restituisce il codice HTML statico per la pagina. L'API Web restituisce i dati JSON del modello di visualizzazione per la pagina. Se non ti piace una vista "vuota" ma vuoi comunque utilizzare Knockout, puoi invece serializzare i dati del modello di visualizzazione su JSON sul server e inserirli nella vista HTML, purché tu non voglia utilizzare AJAX e non importa che l'HTML non sia più memorizzabile nella cache. –

+0

Oggigiorno esistono molte soluzioni per la gestione di applicazioni JS di grandi dimensioni. Nell'anno da quando ho scritto questa risposta, ora abbiamo Breeze.js e Durandal per organizzare tutto e implementare l'impianto idraulico. Scopri il progetto demo di Breeze TempHire. –

1

Per il rilascio URL Aggiungi questo nel vostro _Layout.cshtml in un luogo dove è prima che i file che lo utilizzeranno:

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

quindi è possibile utilizzare il window._appRootUrl per comporre gli URL con la concatenazione di stringhe o con l'aiuto di una libreria javascript come URI.js.

Per quanto riguarda i valori calcolati aggiuntivi, è possibile che si desideri utilizzare un osservabile ad eliminazione diretta calcolato. Se ciò non è possibile o preferisci farlo in .Net, dovresti essere in grado di creare una proprietà con un solo getter, ma questo non si aggiornerà quando aggiorni altre proprietà sul client se dipende da esse.

+0

Grazie per la risposta, esamineremo questo pomeriggio. Mi riferivo all'utilizzo di un osservabile computabile a eliminazione diretta ... mi chiedevo solo come convertire un ViewModel creato dal plugin di mappatura a eliminazione diretta per aggiungere nuovi valori calcolati ... lo estendo in qualche modo? Grazie. –

Problemi correlati