2013-02-17 15 views
8

Dato questo pezzo di codice HTML:Come posso creare un partial riutilizzabile per il markup duplicato in ember.js?

<div id="email_field" class="control-group"> 
    <label class="control-label" for="account.email">Email</label> 
    <div id="email_input" class="controls"> 
    <input id="account.email" name="account.email" type="text" placeholder="[email protected]"> 
    <span class="help-block">We just need a valid email address.</span> 
    </div> 
</div> 

Come faccio a trasformare questo in un riutilizzabile parziale per qualunque attributo che voglio? IE: email, password, conferma password, ecc.

Assumerei una sorta di gerarchia delle viste ma non ne sono del tutto sicuro.

EDIT: Dopo un ulteriore approfondimento che ho buttato giù {{view}} e {{render}} e capito esattamente quello che mi serve:

Voglio: 1. Utilizzare una vista specifica (InputView) 2. Utilizzare un controller specifico (preferibilmente denominato: InputController) ({{view}} non lo fa penso) 3. Essere in grado di utilizzare questo più volte ({{render}} non può farlo) 4. Essere in grado di passare in valori ({{render}} can ' fare questo)

Esempio:

<!-- templates/application.hbs --> 
{{foo "input" name="Email" id="account.email" placeholder="[email protected]"}} 

// controllers/input.js 
Application.InputController = Ember.ObjectController.extend({ 
    type: "text" 
}); 

// views/input.js 
Application.InputView = Ember.View.extend({ 
    templateName: "form/input" 
}); 

<!-- templates/form/input.hbs --> 
<input {{bindAttr id="id" name="name" type="type" placeholder="placeholder"}}> 

risposta

3

I creerebbe una vista che prende tutti i parametri che sono variabili. Come ad esempio:

{{view App.FormEntity 
    name="email" 
    placeholder="My placeholder..." 
    help="We just need a valid email address." 
    valueBinding="value" 
}} 

Da lì si potrebbe estrarre l'etichetta, i vari nomi di classe, e quindi utilizzare Ember.TextField per associare il valore.

Una volta che hai tutti questi argomenti passati nella vista, dovrebbe essere piacevole e facile per creare il markup usando una miscela di bindAttr s, un paio di proprietà calcolate, e aiutanti Ember (come il Ember.TextField).

+1

Grande risposta, grazie, ma mi chiedo quale controller controlla la vista quando si utilizza bindAttr? Non riesco a capirlo dai documenti. – krainboltgreene

+1

Bene, ogni vista dovrebbe avere accesso a un controller. Per impostazione predefinita, se ci si trova in 'IndexRoute', la vista indice avrà accesso a 'IndexController', e se si inserisce una vista in tale vista indice, tale vista erediterà' IndexController'. Forse questo aiuterà: http://stackoverflow.com/questions/14802223/different-rendering-techniques-in-emberjs-handlebars-template/14802424#14802424 – Wildhoney

+0

Interessante, ma non mi aiuta, immagino? Voglio che questo helper abbia il proprio controller. O più specificamente ho valori calcolati che non voglio collegare a IndexController. – krainboltgreene

1

Sono nuovo di Emberjs e cerco praticamente la stessa cosa, ma non è possibile utilizzare semplicemente http://emberjs.com/guides/templates/writing-helpers/? Lo proverò da solo, quindi posso dare più aggiornamenti se questo funziona.

Aggiornamento: Ok, ho capito. Ho creato una nuova cartella aiutanti con FormgeneratorHelper.js e il seguente codice:

Ember.Handlebars.registerBoundHelper('control-group', function (options) { 
    var name = options.hash.test.capitalize(); 
    console.log(name); 
    return new Handlebars.SafeString('<div class="control-group"> \ 
      <label class="control-label" for="input' + name + '">' + name + '</label> \ 
      <div class="controls"> \ 
       <input type="text" id="input' + name + '" placeholder="' + name + '" /> \ 
      </div> \ 
     </div>'); 
}); 

An poi, non importa in quale modello si può fare:

{{control-group test="email"}} 

Mi piace molto l'idea di utilizzare aiutanti, ma se si utilizza il Javascript semplice (al contrario di CoffeScript) e si dispone di più di una riga di codice, purtroppo diventa un po 'brutto. Ma probabilmente utilizzerà ancora questo metodo.

+0

Mentre quello sembra certamente fare quello che voglio, non è sicuramente come voglio farlo. Diventa così impossibile da mantenere. – krainboltgreene

1

Come si trasforma questo in un parziale riutilizzabile per qualsiasi attributo che voglio?IE: email, password, conferma password, ecc.

Quello che vuoi è l'helper sperimentale {{control}}. L'helper del controllo è attualmente in fase di sviluppo ed è considerato sperimentale. Per abilitarlo, impostare ENV.EXPERIMENTAL_CONTROL_HELPER = true prima di richiedere Ember.

Voglio: 1. Utilizzare una vista specifica (InputView) 2. Utilizzare un controller specifico (preferibilmente nome simile: InputController) ({{}} vista non lo fa credo)

Out-of-box l'helper di controllo si aspetta che venga passato un nome di modello. Il nome del modello viene utilizzato per cercare una vista e un controller corrispondenti. Così, per esempio:

App.InputView = Ember.View.extend() 
App.InputController = Ember.Controller.extend() 
{{control input}} 

See:

  1. in grado di utilizzare questo più volte ({{}} rendere non può fai questo)

A control can be used multiple times

  1. in grado di passare a valori ({{}} rendere non può fare questo)

Come il {{view}} aiutante, {{control}} accetterà arbitraria coppie nome/valore. Quindi, come nel tuo esempio, è possibile passare manualmente le opzioni all'assistente di controllo. Come il {{view}} aiutante queste opzioni diventano proprietà nell'istanza vista:

<!-- templates/form/input.hbs --> 
<label class="control-label" {{bindAttr for="view.inputId"}}> 
    {{view.label}} 
</label> 
<div class="controls"> 
    <input {{bindAttr id="view.inputId" name="view.name" type="type" placeholder="view.placeholder"}}> 
    <span class="help-block">{{view.help}}</span> 
</div> 

// controllers/form_input.js 
App.FormInputController = Ember.ObjectController.extend({ 
    type: "text" 
}); 

// views/form_input.js 
App.FormInputView = Ember.View.extend({ 
    classNames: ["control-group"] 
}); 

<!-- templates/application.hbs --> 
{{control "form/input" 
    inputId="account.email" 
    name="email" 
    label="Email" 
    placeholder="[email protected]" 
    help="We just need a valid email address." 
}} 

Vai a questa jsbin ad esempio

lavorando Anche tenere a mente che A control can specify a model to use in its template - con questo in luogo possiamo associare le proprietà di dati del modello. Inoltre, if a controller's model changes, its child controllers are destroyed, quindi il controllo verrà reimpostato come previsto se il modello viene sostituito.