问题
I have the following handlebars template (fragment):
{{#each cbe in abs.XyzBookingEntries}}
<tr>
{{#if cbe.isLoaded}}
<td>{{cbe.XYZdata.ApptDuration}} min:</td>
<td>
{{cbe.XYZdata.ApptType}}
{{#if cbe.XYZdata.ApptTypeDetailCode}}
({{cbe.XYZdata.ApptTypeDetailCode}})
{{/if}}
</td>
<td {{bindAttr class="cbe.XYZdata.statusClass"}}><strong>{{cbe.XYZdata.ApptStatus}}</strong></td>
{{else}}
<td>
Loading...
</td>
{{/if}}
</tr>
{{/each}}
From which you can observe two things:
- I have capitalized attributes on my model
- I have inconsistent capitalization in those attributes (XyzBookingEntries vs. XYZdata)
If I weren't using legacy data sources, I'd be glad to fix both these things. But I have multiple underlying data sources with different developers and different conventions (or lack thereof). Models get from my database to the client via mostly-automated ORM and serialization. And since the conventions are not consistent, automated name mapping (say, with keyForAttributeName
) would be difficult, especially bi-directionally (XYZdata -> xyzdata -> Xyzdata?). But, if it were just a matter of poor conventions I could fix it with documentation.
The bigger problem is that my handlebars template barfs with these names--I think because it wants to interpret them as globals instead of member attributes. I get the following warning message when the below template renders:
WARNING: Watching an undefined global, Ember expects watched globals to be setup
by the time the run loop is flushed, check for typos
Though I do get all the data rendered as expected! And when it is removed from the DOM, I get errors like this:
node is undefined
node.unchain(key, path);
If I watch the variables in the call stack when the warnings and errors come up, the keys I'm rendering in the template can be found (in pendingQueue
, for instance).
The theory that Handlebars thinks they are globals is supported by the fact that if I define the following property:
xyzData: function(){
return this.get('XYZdata');
}.property('XYZdata')
and change all my chains to reference cbe.xyzData.*
instead, the warnings and errors go away!
So, my question is:
Is there a way I can configure/convince Ember/Handlebars to work with the attribute names as is, i.e. to ignore the caps -> global convention? I'd like to avoid hand-mapping a large number of attributes if possible. Open to other possibilities/suggestions as well.
I should mention I'm on 1.0.0-pre4, and am seeing the same behavior with a recent master.
回答1:
Is there a way I can configure/convince Ember/Handlebars to work with the attribute names as is, i.e. to ignore the caps -> global convention?
These conventions are baked-in to the framework pretty deeply, for sure there is no on/off switch.
I'd like to avoid hand-mapping a large number of attributes if possible. Open to other possibilities/suggestions as well.
This is exactly what serializer is for. Sure hand-mapping these attributes sounds like a big lift but unless you're data sources are changing daily it's a one-time thing, and not much more effort than it will take to define the ember-objects in the first place. Another benefit is that you'd encapsulate this mapping in one place, freeing your ember modesl/controllers/views/templates to work with a consistent naming convention. I would seriously recommend investing in this approach. For example:
serializer.map(Cbe, {
xyzdata: { key: 'XYZdata' }
});
With these in place ember will take care of bi-directional mapping for all of your attributes. Have a look at the json serializer tests for more examples of how this might be done.
来源:https://stackoverflow.com/questions/14702224/bypass-disable-uppercase-global-inference-in-handlebars-templates