2011-10-29 38 views
18

Ho osservato il pattern MVVM, in particolare knockoutjs, e soprattutto mi fa rabbrividire. Non voglio andare in un lungo sproloquio sui vantaggi di mantenere la struttura, presentazione e display separato, mi limiterò a chiedere (come esempio): Qual è la differenza tracos'è MVVM e dovremmo usarlo?

<button data-bind="click: someJavaScriptFunction">Something</button> 

e

<button onclick="someJavaScriptFunction();">Something</button> 

e dovremmo mettere così tanto controllo del comportamento nel markup? Per quanto pulito e minimalista come questo, sembra andare contro ogni principio di programmazione web di cui abbia mai sentito parlare.

Mi sbaglio?

+2

Sono sempre stato convinto che dovresti provare a non avere più di una lingua in un singolo file. tipicamente ho impostato un id o una classe e lego la funzione ad esso dopo che la pagina ha finito di costruire. – dqhendricks

+6

Sembra che il problema qui sia meno su MVVM e altro sui pro/contro di JavaScript non intrusivo: http://en.wikipedia.org/wiki/Unobtrusive_JavaScript – Craig

+0

@Craig Avere quel collegamento dati nel markup non sembra nel spirito di non invadente js, quindi non sono sicuro che sia davvero di cosa si tratta. – heisenberg

risposta

7

L'unico utilizzo di una parte di MVVM, in particolare la vista, nell'esempio di codice che hai fornito sopra. La ragione per usare Knockout (o qualsiasi altra libreria MVVM) è di rendere più semplice associare le tue viste a un modello - un modello di vista - consentendo così di smettere di scrivere un sacco di codice boilerplate solo per restituire i valori dalla tua vista.

Vedo un sacco di wonky javascript/codice jQuery dove la gente va e utilizzare qualcosa di simile:

var ex = { 
    some1: $('#textbox1').val(), 
    some2: $('#textbox2').val() 
}; 

Il problema di questo è che è letteralmente disseminato in tutta l'applicazione web e diventa estremamente noioso mantenere. Con Knockout lo so, ogni volta che la mia vista viene aggiornata, anche il mio modello di vista verrà aggiornato.

Non è necessario per tutte le applicazioni e non è consigliabile utilizzarlo solo perché è "cool" da utilizzare. Ovviamente deve esserci una ragione per usarlo, il mio esempio sopra è una delle ragioni e sono sicuro che ce ne saranno altre.

+0

Di cosa stai parlando è l'associazione dei dati. E questo è ciò che in origine mi permetteva di eliminare, ma non è l'unico modo per eseguire il binding dei dati. C'è un plugin jQuery (http://ajaxian.com/archives/jquery-data-binding-templates-and-mobile-john-resig-at-fowa), ad esempio, che consente un'associazione dati molto semplice senza incorporare quella logica vincolante nell'html. – nicholas

+0

L'associazione di dati, come la dom manipulation, la templating o l'iniezione di dipendenza, sono, a mio avviso, comunque, tecniche o strumenti che non fanno parte di alcun modello specifico. – nicholas

+2

@nicholas Sia che tu stia mettendo gli id ​​html in javascript con quella libreria, o i nomi dei campi JavaScript nell'html con knockout, il suo tipo non è lo stesso? La potenza di MVVM non è tanto l'associazione dei dati, quanto il binding comportamentale, quando si ottengono le proprietà dello stato di visualizzazione e non solo le proprietà dei dati consente un modo molto più semplice di sviluppare schermate interattive. Ma come detto sopra non è per ogni caso d'uso, solo un altro strumento nella casella degli strumenti. –

13

Ecco una risposta più diretta alla tua domanda.

Nel secondo esempio, si fa riferimento a una funzione che deve trovarsi nell'ambito globale (ad esempio una proprietà dell'oggetto window).

Nel primo esempio, ci si riferisce a una proprietà del modello di vista corrente.

Sì, è una sottile distinzione, ma è importante. Se si utilizzano gli attributi on-evento, è possibile fare riferimento solo a cose che esistono nell'ambito globale. Ciò significa che devi mettere tutto ciò che vuoi accedere nell'ambito globale, che porta a un codice molto caotico.

Se si utilizzano collegamenti dichiarativi, il significato esatto dei binding dipende invece dal contesto.

Aiuta a pensare al codice HTML come a una coincidenza. Quello che stai guardando veramente è l'accesso strutturato al modello di vista. Pensa a with e forEach come contesti nidificati e agli altri collegamenti come loro attributi. La relazione tra i binding dichiarativi e l'HTML sottostante sembra improvvisamente più come lavorare con XSLT.

I due esempi look molto simili. Ma i concetti sottostanti sono molto diversi e sono ciò che rende l'associazione dei dati così potente e gli attributi on-event così odiosi.

La ragione per cui gli attributi degli eventi sono disapprovati non è solo il fatto che essi mischiano logica e struttura. È che sono un debole tentativo di imbucare codice JavaScript arbitrario in elementi HTML che impedisce il corretto incapsulamento della logica dell'applicazione.Gli attributi on-event sono "hook" di basso livello, i collegamenti estendono il comportamento degli elementi.

Tutto ciò detto, è probabile che sia possibile fare le stesse cose orribili che le persone hanno fatto con gli attributi on-event usando i binding dichiarativi. La differenza è in che altro si può fare con loro. Non dovresti sempre giudicare le tecnologie in base a come possono essere abusate - siamo tutti adulti qui.

+1

FWIW, probabilmente non troverai i binding estremamente utili al di fuori delle applicazioni a pagina singola (leggi: app web che si basano molto su JavaScript). Potrebbero essere utili per legare semplici widget come datepickers, ma è difficile trovare un caso d'uso per i normali siti web che non potrebbero essere facilmente replicati con selettori CSS e jQuery. –

+0

Grazie Alan. Questa distinzione ha molto senso. +1 – nicholas

+0

Ma l'ambito del javascript chiamato non ha più a che fare con il modo in cui organizzi il tuo script che se debba esistere o meno nel markup. Potrei anche fare qualcosa di simile (per usare una comune sintassi jQuery) onclick = "$ (this) .data ('myplugin'). SomeFunction()" per chiamare una funzione scoped usando il gestore onclick. – nicholas