2015-05-19 7 views
6

Sto riscontrando un comportamento strano quando i dati collegano un oggetto a un modulo che mi ha portato a ri-interrogare su cosa esattamente si stanno vincolando i dati?JsViews come rendere possibile l'associazione dei dati sull'oggetto radice e le sue proprietà nidificate?

Fondamentalmente ho un modulo che crea nuove società e le aggiorna. L'effettiva creazione/aggiornamento avviene tramite ajax, motivo per cui sto utilizzando lo stesso modulo per entrambi gli scopi. Nel caso in cui devo creare un'azienda, tutto funziona come mi aspetto. Tuttavia, quando devo aggiornare un'azienda, le cose non funzionano come mi aspetto che facciano. Si prega di dare un'occhiata al seguente codice.

Ecco il mio modulo di esempio HTML:

<div id="result"></div> 

<script type="text/x-jsrender" id="CompanyFormTemplate"> 
    <form> 
     <input type="text" data-link="Company.Name" /> 
    </form> 
</script> 

Ecco il mio codice Javascript:

var app = new CompanyFormContext(); 

function CompanyFormContext() { 
    this.Company = { 
     Name: '' 
    }; 

    this.setCompany = function (company) { 
     if (company) { 
      $.observable(this).setProperty('Company', company); 
     } 
    }; 
}; 

$(function() { 
    initPage(); 

    ... 

    if (...) { 
     // we need to update company information 

     app.setCompany({ Name: 'Company ABC' }); 
    } 
}); 

function initPage() { 
    var template = $.templates('#CompanyFormTemplate'); 
    template.link("#result", app); 
} 

Al posto del modulo di input che mostra 'azienda ABC', è vuota. Tuttavia se inserisco qualcosa in esso, il valore di Company.Name cambia! Ma mentre voglio che l'input ai dati si leghi alla proprietà Name dell'oggetto della mia azienda, voglio anche che sia a conoscenza di eventuali modifiche apportate all'oggetto aziendale (padre) e aggiorni il suo binding ai dati della sua proprietà Name di conseguenza.

Quindi la mia domanda è: come dovrei cambiare il modo in cui sto scrivendo questo codice in modo da poter ottenere un collegamento dati sia sull'oggetto radice che sulla proprietà?

risposta

3

Il problema riscontrato era che, nel tuo scenario, esistono percorsi come Company.Name per i quali si desidera il collegamento dati alle modifiche non solo della proprietà foglia ma anche alle modifiche che comportano la sostituzione di oggetti più in alto nel percorso (in questo caso l'azienda).

Per questo è necessario utilizzare la sintassi data-link="Company^Path".

Vedere la sezione Percorsi: modifiche foglia o cambiamenti profondi in questo argomento della documentazione: http://www.jsviews.com/#[email protected].

Vedere anche gli esempi come Esempio: JsViews con oggetti semplici e matrice in questo argomento: http://www.jsviews.com/#explore/objectsorvm.

Ecco un aggiornamento di jsfiddle, utilizzando la sintassi: https://jsfiddle.net/msd5oov9/2/.

BTW, FWIW, nella vostra difficoltà utilizzando {^{for}} voi non ha dovuto utilizzare un secondo modello - si potrebbe in alternativa hai scritto:

<form class="form-horizontal"> 
    {^{for Company}} 
     ... 
     <input type="text" data-link="Name" /> 
    {{/for}} 
</form> 

Per rispondere anche alla tua domanda di follow-up nel vostro commento qui sotto , puoi associare qualsiasi tag 'blocco' con un modello. L'utilizzo di tmpl=... sul tag significa che hai deciso di separare quello che sarebbe stato il contenuto del blocco in un modello riutilizzabile separato. (Un 'parziale', se vuoi). Il contesto dati per quel modello sarà lo stesso di come sarebbe stato all'interno del blocco.

In modo specifico, i tag {{include}} {{if}} e {{else}} non spostano il contesto dei dati, ma {{for}} e {{props}} lo fanno. Con tag personalizzati si può decidere ...

Quindi nel tuo caso è possibile utilizzare uno o {^{for Company tmpl=.../}}{{include tmpl=.../}} ma nel secondo caso il vostro altro modello che si fa riferimento userebbe <input type="text" data-link="Company^Name" /> piuttosto che <input type="text" data-link="Name" />.

Ecco alcuni link utili:

+0

Grazie mille per aver condiviso i link alle sezioni appropriate! Ironia della sorte, avevo attraversato entrambe le sezioni ad un certo punto nel passato, ma quando stavo scrivendo questo codice non mi è venuto in mente che era quello che dovevo fare. Una domanda minore: c'è qualche altro costrutto che dovrei usare per indicare il rendering di un oggetto usando il modello X invece di? –

1

Ho scoperto un modo per raggiungere questo obiettivo. Potrebbe sembrare complesso all'inizio, ma avrà senso una volta capito bene.

(PS: Vorrei che ci fosse un campione come questo potrei blog su di esso..)

Tag HTML:

<script type="text/x-jsrender" id="CompanyFormTemplate"> 
    <form> 
     {^{for Company tmpl="#CompanyDetailsTemplate" /} 
    </form> 
</script> 

<script type="text/x-jsrender" id="CompanyDetailsTemplate"> 
    <input type="text" data-link="Name" /> 
</script> 

Javascript: Nessun cambiamenti necessari dal codice di cui sopra.


Va bene così come ho detto, la soluzione potrebbe sembrare complicato ma si scopre tutto ho dovuto fare era di creare l'associazione di dati prima sull'oggetto società, e quindi alla sua oggetti di proprietà. Mi chiedo se esista una soluzione più elegante (vale a dire una in cui tutto questo può essere ottenuto in un singolo modello), tuttavia questa soluzione garantisce che l'associazione dei dati avvenga sia sull'oggetto padre sia sulle sue proprietà.

Ho postato un JsFiddle per questa soluzione, quindi se qualcuno incontra questo problema e vuole capire come questa soluzione potrebbe funzionare per il loro particolare problema, sarà in grado di giocare con una soluzione funzionante.