-
-
Notifications
You must be signed in to change notification settings - Fork 4.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
buffer.string() doesn't work #5534
Comments
The error is correct. You can't manually render a view like this outside of the rendering process. You probably don't want to do In theory, you could try
Instead, I recommend compiling your own templates with Handlebars.compile (not Ember.Handlebars.compile) these are better suited for what you want to do. |
Ah ok, sorry for the trouble. |
@amk221 No trouble at all. :) |
@mmun Would it be reasonable to Ember.View to have a public function that would allow its template to be rendered to a string, using unbound properties from a given context? Third party libraries that need a string of HTML seem inevitable. In 1.0.7 I was happily sharing my view templates. |
@aceofspades That sounds reasonable. Could you explain the use case more? Why do you want to use an Ember Handlebars template for this, rather than a vanilla Handlebars template? Are you using it both the "standard" way as well as for string serialization? |
I assume vanilla would be just fine. Adapting your example
bombs on _triageMustache which is calling Is there some other way to fetch the raw template markup that I'm missing so handlebars could be used directly? |
Vanilla Handlebars-compiled templates don't use a buffer. That's a construct unique to the Ember Handlebars compiler and Ember's view layer. Here's an example of what I meant by a vanilla template var template = Handlebars.compile("Hey {{name}}!");
var output = template({name: "aceofspaces"}); |
Even better--all I am missing now is how to fetch the raw markup from the template. Am I missing something blatantly obvious? |
@aceofspades not sure what you mean. The output is a string of HTML
|
@mmun The input is the problem, i.e. getting |
The template source is not accessible. Yes, you'll need to set up ember-cli to precompile them with Handlebars.precompile vs Ember.Handlebars.precompile but I don't think such an add-on exists. |
Ah yes - I think the confusion comes from the work ember-cli kindly does. One assumes that the precompiled ember-handlebars-templates would be useable for non-ember stuff.
|
It seems there is a feature loss, not listed as a breaking change, from 1.0.7 to 1.0.8, that a precompiled template cannot be rendered to a string outside the context of the DOM (maybe this can be stated more accurately by someone more familiar with internals). Several posts on discourse and elsewhere show how to render to a string and no longer work. This seems like an important feature to have, it certainly breaks my app. @mmun thanks for taking the time to comment. |
My use case is to integrate with ember-selectize, an integration between ember and selectize. Selectize accepts render functions to render its options, items, etc. These functions have to return strings. I understand the problem. I'm using bindings in my template, I can't expect the bindings to work with a string. But would it be possible to render an Ember template without bindings (just using the current context)? So, i guess this feature may be important to integrate with other libraries (like i've seen here with typeahead.js). Related issue: miguelcobain/ember-selectize#13 |
@amk221 "One assumes that the precompiled ember-handlebars-templates would be useable for non-ember stuff." <- This is not true, and has never been suggested. @aceofspades Still unsure what you are referring to. You can ask Ember for a buffer's string. In general, Ember is supposed to manage the rendering of your templates into DOM. What is your use-case for doing something different? @miguelcobain that is the kind of behavior we would want to see provided by interoperable web components. This is easiest to do when the components all speak DOM, since that is the universal UI language of of the web. That selectize expects a string of HTML will make it challenging to use with Ember templates. Using Another option to consider is authoring a helper instead of a view. This would be a bit lower-level, and allow you to bypass Ember's views and data binding. With HTMLBars, you will need to get the outerHTML or innerHTML of the helper's block (since the inner block would return DOM). In Handlebars the raw string would be available to you. At the end of the day, regardless of how well we can support strings, Ember is going to have a DOM based rendering engine internally. A string-based rendering engine is far too slow to be viable in the long-term. Using DOM will also enable a bunch of fantastic new syntaxes that make authoring templates easier. I urge you to keep in mind that although supporting strings of HTML is still something we will do for existing APIs in 1.x, you should consider avoiding string HTML in your own code for the same reasons. |
@mixonic very informative. I'm also a contributor to ember-leaflet, and we had this problem when trying to use Ember views for some marker popups in a map. Things worked great there because leaflet accepts DOM elements. I'm aware that selectize expects strings and that's the problem. I'll open a ticket there, or maybe I'll try to implement that myself. Don't know how difficult that might be. My first thought was that if selectize just took the DOM element from our function and take a string from it and continue, wouldn't it work? Thanks! |
@mixonic There are posts on github and discourse where core members have shown how to render a view to a string. This procedure no longer works in 1.8.0 so I'm saying this is a breaking change. I am confused why this would be opposed. Aren't there are not tons of libraries out there that work with HTML strings, and other reasons we might want to leverage a template and render to something other than the browser DOM? Ember shouldn't cripple developers, expect every library to accommodate ember's "better way", or reinvent the wheel and rewrite already proven code. My current pain point is also selectize. Render hooks are used to generate markup that is used elsewhere in the app to display a common metaphor. I'd really prefer to be able to keep one template that I can render manually as needed to make the plugin happy, so I can concentrate on my business logic. Personally I don't think this is selectize's problem, and there are 217 open tickets there anyway. |
@aceofspades, are you using ember-selectize? We should try to encapsulate whatever the outcome of this is in that repo. Ember always encouraged best practices. Since "using html strings" isn't one of them, I'm not surprised it isn't easy to do with ember. But I would love a solution for this. |
Yup, I agree the RenderBuffer is public. I think I explained why we do not encourage strings in my last comment. It is a better way, and our goal is definitely not to "cripple" developers :-( Let's keep the emotions steady :-) |
Fwiw, that JSBin looks correct for rendering a string, but it doesn't seem to in 1.7 or 1.6. |
Can we get a JSBin with this dis-connected render buffer behavior working in 1.7 or before? |
Agreed ember should do things the better way, within its scope. We just need an escape hatch to leverage all the code that's out there. Cloned jsbin, working with 1.7.0: http://jsbin.com/poqus/1/edit |
Ok, several points. @aceofspades I don't think I can make you happy here, but I'm going to lay things out in as much detail as possible.
The last point highlights what I think may be the crux here: http://emberjs.com/api/classes/Ember.RenderBuffer.html#method_string
A far more sane way to achieve similar behavior is to use http://emberjs.com/api/classes/Ember.View.html#method_createElement
A JSBin using this API: http://jsbin.com/newub/4/edit?html,js,output I suggest this with a caveat: Ember's view layer is not designed to be used in an ad-hoc manner like this. In-fact this codepath ( I am again closing this issue. |
Thanks @mixonic for the detailed explanation. My original use-case was a bit different. Forgetting about the original workaround, and stated more simply, I would like to fetch a component's simple, raw template and compile it with handlebars at runtime. Since ember-cli precompiles templates this appears not to be possible. The alternative seems to be to declare markup in javascript rather than hbs. |
@mixonic thanks this information has been really useful. It makes sense why we're moving in that direction. The examples helped but I still haven't been able to solve this problem. We have two different use cases with external libraries.
All of this was working just fine in Ember 1.4 (yes we're behind I know - trying to catch up). Your example of using However, if we need to use nested components it can't find them. jsbin. So we have to use For the second scenario, it seems to be working fine, but without the nested components working I've not been able to verify all instances. For this to work, I'll also need to tweak/hack a few of our external libraries, but it's certainly doable. Before I go down that path, has anything changed since Oct 27? |
This seems hacky, but actually better than what we had with 1.4. It makes sense that render doesn't call didInsertElement, so we simply call it manually see jsbin after the element is inserted into the DOM. Not included in this jsbin, but we do something equivalent for other events like willDestroy. There's another jsbin that tests bindings and actions. Simple change was to use the element instead of the string. Now I need to look at the real world scenarios. |
Oh, I found another problem with this approach. Even though, BoundViews work, |
I was trying to use the
Here is a JSBin: http://emberjs.jsbin.com/dumiboroju/1/edit?html,js,console,output However, the string is still rendered. |
Appending a view renders the buffer to a string, but one cannot access the string() directly.
example failure: http://jsbin.com/hafubakokape/1/edit?js,output
related forum post: http://discuss.emberjs.com/t/how-to-render-a-template-to-a-string/6136/7
The text was updated successfully, but these errors were encountered: