2016-04-08 7 views
1

Ich habe ein JSON-Objekt, nennen wir es teamData mit Teams.Lenker mit zwei verschiedenen Eigenschaften. Helfer oder teilweise?

Ich möchte in der Lage sein, eine Variable wie Primary oder Secondary an einen Aufruf zu übergeben und es eine Status Dropdown mit dem Status des TeamType ausgewählt werden zu lassen.

Ich habe viele Tutorials gelesen, aber keiner von ihnen behandelt wirklich mehr als eine Eigenschaft eines Objekts oder zeigt, wie man einen Wert von einer Eigenschaft mit einer anderen verknüpft.

die Staaten Dropdown ist einfach

<script type="text/x-handlebars-template" id="tmpl-states"> 
     <select> 
      {{#eachProperty States}} 
       <option name="{{property}}">{{value}}</option> 
      {{/eachProperty}} 
     </select> 
</script> 

Handlebars.registerHelper('eachProperty', function (context, options) { 
    var ret = ""; 
    for (var prop in context) { 
      ret = ret + options.fn({ property: prop, value: context[prop] }); 
    } 
    return ret; 
}); 

aber, was ich will zu tun ist mehr wie (in sudo)

renderTemplate("tmps-all", "container", "data", "variable"); 

<script type="text/x-handlebars-template" id="tmps-all"> 
     {{#each Teams}} 
      {{#if TeamType == variable}} // e.g. Primary 
       var State = this.State; 
      {{/if}} 
     {{/each}} 
     <select> 
      {{#eachProperty States}} 
       {{#if property == State}} // e.g NY 
       <option name="{{property}}" selected>{{value}}</option> 
       {{/else}} 
       <option name="{{property}}">{{value}}</option> 
       {{/if}} 
      {{/eachProperty}} 
     </select> 
</script> 

var teamData = {"Teams":[{"TeamType":"Primary","State":"NY"},{"TeamType":"Secondary","State":"CA"}],"States":{"AK":"Alaska","AL":"Alabama","AR":"Arkansas","AZ":"Arizona","CA":"California","CO":"Colorado","CT":"Connecticut","DC":"District of Columbia","DE":"Delaware","FL":"Florida","GA":"Georgia","HI":"Hawaii","IA":"Iowa","ID":"Idaho","IL":"Illinois","IN":"Indiana","KS":"Kansas","KY":"Kentucky","LA":"Louisiana","MA":"Massachusetts","MD":"Maryland","ME":"Maine","MI":"Michigan","MN":"Minnesota","MO":"Missouri","MS":"Mississippi","MT":"Montana","NC":"North Carolina","ND":"North Dakota","NE":"Nebraska","NH":"New Hampshire","NJ":"New Jersey","NM":"New Mexico","NV":"Nevada","NY":"New York","OH":"Ohio","OK":"Oklahoma","OR":"Oregon","PA":"Pennsylvania","PR":"Puerto Rico","RI":"Rhode Island","SC":"South Carolina","SD":"South Dakota","TN":"Tennessee","TX":"Texas","UT":"Utah","VA":"Virginia","VT":"Vermont","WA":"Washington","WI":"Wisconsin","WV":"West Virginia","WY":"Wyoming"}};

Antwort

1

Es besteht keine Notwendigkeit für Ihr eachProperty Helfer. Die Funktionalität, die es Ihnen gibt, existiert bereits in Lenker. Lassen Sie uns diesen Helfer entfernen und unsere Vorlage an die folgende Aktualisierung (Anmerkung: Ich werde das name Attribut mit value ersetzen):

<select> 
    {{#each States}} 
     <option value="{{@key}}">{{this}}</option> 
    {{/each}} 
</select> 

nun auf die Aufgabe zugeschrieben, die selected der Einstellung.

Sie versuchen zu viel Logik in Ihre Vorlage. Es ist nicht für die Vorlage Variablen zu initialisieren. Diese Arbeit sollte getan vor die Vorlage wird gerendert. Wir möchten, dass unser Code die Template-Methode aufruft, um der Vorlage alle Daten zu geben, die sie benötigt. Dies würde bedeuten, zu unserem Template wie diese eine Datenstruktur übergeben:

[ 
    { 
     value: 'AK', 
     label: 'Alaska', 
     selected: false 
    }, 
    { 
     value: 'AL', 
     label: 'Alabama', 
     selected: false 
    }, 
    // and so on... 
] 

Unser Code wird die Arbeit der Aufbau dieser Datenstruktur tun:

var selected_team = teamData.Teams.find(team => team.TeamType === 'Primary'); 
var states = Object.keys(teamData.States).map(key => ({ 
    value: key, 
    label: teamData.States[key], 
    selected: (key === selected_team.State) 
})); 

Jetzt können wir unsere Vorlage ändern unsere neuen Daten zu handhaben Struktur:

<select> 
    {{#each this}} 
     <option value="{{value}}" {{#if selected}}selected{{/if}}>{{label}}</option> 
    {{/each}} 
</select> 

Wenn wir unsere Vorlage nennen wir einfach in unserem states Variable übergeben:

012.351.

Allerdings: Mit all diesen Arbeiten hinter uns, möchte ich hinzufügen, dass ich keinen Zweck sehe, diese Vorlage neu zu rendern, nur um eine geänderte ausgewählte Option widerzuspiegeln. Es macht mehr Sinn, das DOM zu nutzen, um die Änderung vorzunehmen. So etwas wie die folgenden würde genügen:

document.querySelector('#Select [value="NY"]').selected = true; 

See: https://stackoverflow.com/a/7373115/3397771

+0

sehr schön! Ich habe mich nicht viel mit ecmascript und seinen neuen Prototyp-Funktionen beschäftigt, aber Ihr Ansatz macht viel mehr Sinn - die Daten sollten in erster Linie neu strukturiert werden und der Lenker sollte nur als Vorlage verwendet werden. Was ist ein gutes Tutorial, das ähnliche Beispiele wie Sie verwendet hat? Insbesondere das Prädikat, das Sie mit der Methode find verwenden – archytect

+0

MDN ist immer gut: https: //developer.mozilla.org/de/docs/Web/JavaScript/Referenz/Funktionen/Arrow_functions – 76484

+0

Der äquivalente Funktionsausdruck wäre: 'function (team) {return team.TeamType === 'Primary'; } ' – 76484

Verwandte Themen