I have made element directive, which works with template through templateUrl parameter. This template contains fileupload input, which needs about 8 external js libraries (jquery fileupload plugin). If I have links to these js libraries in template (using standard script element), than everything works fine, but there is an error in browser console on loading:
Error: $digest already in progress
If I put the links to js libraries directly to the page, where I have my directive, there is no error, but it is not good way for reusability.
Are you trying to trigger a $digest manually?
If this is the case, I strongly recommends you to change the approach, as you should let the Angular decides the best time for a $digest. If it's not possible to change, then you should be sure you're not calling a $digest()/$apply() inside an $digest cycle. One of the ways to do so is ensuring !scope.$$phase.
Related
I used ember generate to create a header component for a youtube video I am following. I have a few questions -
When I ran ember generate component header, the terminal responded with creating the header.hbs file in app>components, but then skips header.js in app/components. I manually created a header.js file in that directory and if I do an alert() in the js file it works.
I have the following code in my header.hbs file.
<h1>Hello There!</h1>
{{yield}}
In my application.hbs file :
<Header/>
{{outlet}}
thoughts, suggestions? Thank you for any help in advance!
Let me try to explain this a bit. Basically there are 4 kinds of components in ember.
without a .js file:
When you invoke a component ember will first look up the component class. When it does not find such a class the behavior depends on the optional feature template-only-glimmer-components. This is by default enabled for new octane apps.
If it is enabled ember will look up the component template based on some standard rules and use it, but there will be no backing class. That is pretty nice. This is also basically what you get in a octane app when you do ember g component my-component.
When template-only-glimmer-components is disabled then an implicit classic component class will automagically be created and used together with the correct template. You don't want this behavior. If you still have it you can migrate away from it by 1) creating a .js file for every component and then 2) enabling template-only-glimmer-components.
with a .js file
When a js file is found ember will get the default export of that module. Then it will look up the correct component manager. This actually depends on that export: setComponentManager should have been called on it. This is usually done in a base class as #ember/component or #glimmer/component.
But you can also write your own custom component manager.
Basically ember will then also look up the template based on that component. A public API for this is proposed in this RFC, but currently a private API is used for the so called template co-location where you place your .hbs file next to your .js file with the same name and just a different extension. This is the default in octant. Here a ember internal build-step in ember-cli basically adds your template to the .js file and uses that API. You can also see the result in a browser debugger. So when there is no default export then ember can not find your template.
I adopted a legacy project that uses EmberJS 2.5.1, and I have a component that is unable to use the JQuery UI Sortable method. The vendor folder contains jquery.ui.min.js, and ember-cli-build.js imports it.
This is what I currently have in my code:
Ember.$("#cute_table_of_puppies_eating_clowns tbody").sortable({})
(Sortable has been simplified for example purposes...)
In Chrome's Debugger it converts to...
_ember["default"].$("#cute_table_of_puppies_eating_clowns tbody").sortable({})
The JQuery selector works, but it cannot find the selector. I put a break point on that line, and tried $("#cute_table_of_puppies_eating_clowns tbody").sortable({}) from the console. This ends up working.
What do I need to do to properly use this function from a component?
I am using EmberJS with HandleBars and using the Yeoman setup, (but I updated dependencies to the latest).
I have a relatively large application.hbs, and I want to separate it into different files like top-bars.hbs and main-content.hbs and so on, then I want to include them in the application.hbs. but I do not have any views for them, just some separation of the big file, I do not want to make ajax requests for those templates, just want to separate and then include them.
How can I do this in emberJS?
I think what you maybe looking for is a partial. What you would do is make a partial file in the directory you want most likely somewhere with all the other templates. The resolver complains about either leading underscores or dashes in Yeoman so if one blows up try the other this is mostly for a visual indication when looking through your files which ones are partials. So make _top-bars.hbs and put the code you want in there. and the in the application.hbs just do `{{partial "top-bars"}} and it will put the template into the application template without changing the scope.
I am having a lot of scripts written inline along with the HTML. Now, I am trying move the scripts to an external file. But, most of my scripts uses django variables and if.else statements. So, I am not able to move these scripts to an external files. Is it possible to use django template variables/conditions in scripts loaded from external file?
What you are asking for is a client-side include, in order to ultimately retain the external file as a "link". That means the main page loads, and then the external content is loaded, all client side. Yet you want the include to be django-processed.
Django templates are rendered server-side, meaning that they have to be evaluated with the context, server side. The main page has to fold the includes into it in order to serve it to the client. Thus, what you are asking for is possible, if you accept that you can keep your content in external files, but they will be rendered in the same page.
Otherwise, you would have to do something more complicated like have javascript load the external pages, passing the same context information back to the server, which can render the template through a different url endpoint. Or just rely on the session data, and have the other url render its page completely on its own.
Did you use include. Make an another html file and include it parent template.
You can pass additional context to the template using keyword arguments:
{% include "name_snippet.html" with person="Jane" greeting="Hello" %}
I'm using precompiled templates for several reasons:
Performance (no need to re-compile at runtime)
Code separation (cleaner than embedding <script> tags and hardcoding in JS)
Content security policy (this is for an extension).
Basically, I'm generating templates.js via the handlebars command line utility, based on several template.handlebars files. Next I try to bring these templates into Ember with the following loop:
for (var name in Handlebars.templates) {
var template = Handlebars.templates[name];
Ember.TEMPLATES[name] = template;
}
The result is weird: text seems to be loaded, but many template features (eg. {{outlet}}) don't work. I suspect that this is because Handlebars and Ember-Handlebars are not the same thing.
I guess there are two options (and questions):
Precompile Ember-friendly templates (how can I do this via a command line?)
Properly import Handlebars templates into Ember (how?)
UPDATE: As per the answer, Ember.Handlebars is not the same as Handlebars, so the precompilation is different. Wrote a simple script to precompile for Ember: https://gist.github.com/3723927
Yes, the plain Handlebars compiler compiles to different JavaScript than Ember.Handlebars, so you cannot consume its output with Ember.
I don't know of a way to run Ember.Handlebars through the command line, though it should be possible in principle to write something.
To find out how to precompile with Ember.Handlebars, take a look at the source code of ember-rails - it supports precompilation.