9

Sono ancora un po 'confuso da come deve funzionare MVC.Real World MVC - Gestione dei moduli

Diciamo che ho un sito Web che vende widget. Ho una pagina di elenco, /widgets/list e una pagina di prodotto /widgets/product/123.

Entrambi possono utilizzare il controller widget e chiamare i metodi list e product - abbastanza semplici finora. Diciamo che ho anche diversi altri controller per varie cose.

Ora aggiungo una casella di iscrizione alla newsletter nell'intestazione, ad esempio su ogni pagina del sito. Come funziona? Ho l'idea che debba essere inviata a /newsletter/signup

Ma cosa succede se c'è un errore (ad esempio non hai inserito correttamente il tuo indirizzo email)? Dovrebbe mostrare la pagina in cui ti trovavi (ad esempio /widgets/list) ma il controller newsletter deve essere eseguito. Il controller widget non conosce il controller newsletter, quindi non posso inserire il codice lì ... Come funziona?

Modifica: No AJAX per favore - lo capisco più facilmente. Considera questo il fallback quando javascript è disabilitato.

Edit 2: Alcune esempi o tutorial che coprono questo genere di cose sarebbe molto apprezzato

Edit 3: E 'ammissibile per una vista da chiamare un'azione? Ad esempio l'intestazione potrebbe chiamare Newsletter->index()

risposta

0

È necessario inserire il messaggio di errore in un punto globale in cui il controller di pagina (che include i "subcontrollers" newsletter) può prelevarlo.

In caso di AJAX, è possibile fare in modo che il controller newsletter chiami allo DIV in cui sia visibile (poiché non si sta ricaricando l'intera pagina). Per questo, avrai bisogno di un pezzo di JavaScript nella pagina che viene chiamata quando termina la richiesta AJAX che prende la stringa e la mette dove vuoi tu.

0

La mia esperienza MVC è più pratico e meno "quello che dice il libro", ma qui va:

Avresti una classe di controller di base (in CakePHP - che è quello che mi è più familiare con - è chiamato AppController) che è sottoclassato da tutti gli altri controller. Questa classe implementerebbe tutte le cose "globali" di cui stai parlando.

Esempio pratico:

Nella mia classe AppController, il quadro definisce un callback beforeFilter() che viene eseguita essenzialmente su ogni caricamento della pagina. Qui è dove vorrei verificare se il modulo di iscrizione è stato presentato e gestirlo in modo appropriato. Se la registrazione ha preso una schifezza in qualche modo, aggiungerei qualcosa alla sessione indicando così tanto e la mia vista controllerebbe semplicemente l'esistenza di un elenco di errori provenienti dal modello di newsletter e, se sono lì, mostrali.

Questo è probabilmente un po 'più pesante sui dadi e bulloni e più leggero sulla teoria di quello che stavi chiedendo, ma non ho alcuna formazione in tutto questo schifo, quindi c'è la mia migliore :)

1

Aggiungere un campo al modulo newsletter, che memorizza l'URL della pagina corrente. Quando si verifica un errore durante l'invio della newsletter, recuperare l'URL e reindirizzare a quella pagina. A condizione di inserire le informazioni di errore nel posto giusto, dovrebbe essere raccolto dal modulo di newsletter che, si dice, è incluso in ogni pagina.

0

Per i widget che devono restituire alcuni errori di convalida ecc. - utilizzare partial requests (oi subcontrollori da MvcContrib) + AJAX.

0

Quello che faccio è che ogni modulo sia pubblicato su se stesso. Nel controller, controllo se la variabile post è impostata; se è così, faccio la convalida. Se la convalida ha esito positivo, eseguo un reindirizzamento a un'altra pagina. Se fallisce, la pagina del modulo viene semplicemente ricaricata con messaggi di errore. Ciò semplifica e riduce la duplicazione del codice. Vedi qui:

**in controller**: 

If post variable is set: 
    validate form 

    if form is validated: 
     redirect to new page (or whatever) 
    else: 
     add error messages to the $data variable of the view 
    endif 

endif 

//$data contains whatever information you'd normally pass to the view. 
//if there was a validation error, the messages are added to the $data variable 
show view with $data variable 

Come si può vedere, il flusso rientra sempre nella singola istruzione di caricamento della vista. Tuttavia, se la convalida ha esito positivo, sei portato in un'altra pagina.

+0

Se ho un sito Web esistente con 10 controller, ciascuno con 5 azioni, non significa che dovrei modificare 50 funzioni se ho aggiunto una registrazione alla newsletter nell'intestazione? – Greg

+0

Beh, questa sarebbe l'eccezione in cui pubblica una pagina separata. La maggior parte dei moduli non appare su più pagine, solo cose come newsletter, login e forse registrazione. Nel complesso, quanto sopra è piuttosto efficace. – ryeguy

6

Non vedo perché il messaggio di errore per la casella della newsletter presente su ogni pagina, deve essere visualizzato nella stessa pagina. Se si dispone di una pagina che invia a un'altra azione, completamente non correlata alla vista corrente (ad esempio, ricerca), non vi è alcun motivo per cui il messaggio di errore venga visualizzato nella pagina originale. Mostreresti il ​​messaggio di successo sulla stessa pagina? Dove sarebbe gestito?

I messaggi di errore per il modulo della newsletter devono essere visualizzati in una vista dedicata alla newsletter. Ad esempio, vedi come è fatto in StackOverflow - vai nella casella di ricerca e digita nulla, semplicemente premi invio. Questo è un tipo di errore poiché non hai specificato cosa vuoi cercare. Stackoverflow ti porterà quindi a una pagina diversa che spiega come funziona la ricerca.

Ora, perché l'ha fatto? Il motivo è semplice: l'utente era su una pagina e ha scelto di dedicarsi a un'attività che non è correlata alla pagina corrente, quindi non c'è motivo di mantenerli lì.

+0

Anche se posso immaginare che l'OP voglia tornare alla vista originaria, probabilmente sceglierei anche l'approccio suggerito. –

+2

Per aggiungere a ciò: Per mantenere un "indicatore" di dove era l'utente scorso, è possibile utilizzare i cookie o aggiungere una stringa di query all'URL. Ad esempio: '/ newsletter/registrazione? Return_to = widget/elenco' –

+0

+1 Dal mio punto di vista è completamente corretto e accettabile reindirizzare l'utente a un altro controllore per informare di successo/insuccesso. –

0

Come aggiungere un campo nascosto alla pagina che invia al controller/newsletter/registrazione con l'url di dove andare dopo che il controller è terminato, ovvero la pagina corrente (oppure è possibile utilizzare l'intestazione http di riferimento).

Questo controller aggiunge quindi un elenco di messaggi di errore o un messaggio di successo a un elenco di oggetti da rendere dalla vista prima di inoltrarli al controller specificato dal campo nascosto in alto. Questo controller aggiunge quindi la sua lista di oggetti da visualizzare nella vista (ad esempio l'elenco dei widget).

Quindi, nella vista, è possibile visualizzare i messaggi di errore dal controller della newsletter, se presente.

1

C'è un buon centro ASP.net MVC tutorial che descrive i metodi per includere i widget (componenti riutilizzabili) in un ambiente MVC.

L'idea di base è quella di impostare i widget con la propria pipeline di richiesta, non amalgamarli in un controller/vista combinato che vanificherebbe la manutenibilità di MVC.