Ember JS CollectionArray Flickering - ember.js

When you have a large collection of objects in an ArrayController, you can sometimes see the list gradually building on the page when you switch to that view.
Is there a way to only show the view after the list has been built, in order to avoid a flickering interface?

Is there a way to only show the view after the list has been built, in order to avoid a flickering interface?
It sounds like what you need is Ember.ListView - it improves performance for very large collections by rendering just enough rows to fill the visible area.
{{#collection Ember.ListView contentBinding="controller" height=500 rowHeight=50}}
<!-- row content here -->
{{/collection}}
Demo on jsbin: http://jsbin.com/ucegit/1/edit
https://github.com/emberjs/list-view

Related

Render table component with 500 rows block browser?

I have a component which render 500+ data into a HTML table rows
It take almost 3 seconds to render and the browser is completed blocked.
I cannot use pagination because the client want it excel-like and it is a static site.
Is there a way to solve this issue? For example create a loading state before the component is rendered?
I guess 500+ row does not fit to the screen (viewport), so you need to use a scroll.
There is an addon named ember-in-viewport. It gives you the ability of not rendering the component if it is not in viewport.
Here is a sample twiddle. Change my-component to my-proxy-component in your applicaiton.hbs to see the effect.
Don't render all the objects at once, just load what's visible inside your viewport. There are already different Ember addons doing exactly what you need.
Some addons you could use:
Vertical Collection
Ember Infinity
Ember Light Table
P.S. Of course you could also create a component/addon yourself and use the ember-in-viewport addon #ykaragol suggested, but I think that's overkill in your situation.

How to prevent views from being destroyed in Ember.js

Quick note:
I don't believe this is a duplicate of Ember.js: Prevent destroying of views. Other related questions that I've found are out-of-date.
In case this becomes out-of-date later, I am using Ember 1.7.0 with Handlebars 1.3.0.
Context for the question:
As the title states, I am wondering how to transition between views without destroying them. Using queryParams does not solve my issue.
I am creating a calculator with the following nested views:
>>Calculator View
>>Report View (hasMany relationship to Calculator)
--School Partial (I am using queryParams here)
I am able to navigate between the Report views just fine without destroying my School partial, since I am using queryParams and using a displaySchoolPartial boolean to show/hide the partial. Example below:
Report template (stripped to only show the essential part):
<script type="text/x-handlebars" data-template-name="calculator/report">
...
{{#link-to "calculator.report" (query-parameters displaySchoolPartial="true")}}
{{render "_school"}}
</script>
School template (also stripped down):
<script type="text/x-handlebars" data-template-name="_school">
{{#with controllers.calculatorReport}}
<div {{bind-attr class=":schoolPartialWrapper displaySchoolPartial::hide-element"}}>
...
</div>
{{/with}}
</script>
This works as expected. Navigating between different Report views and School partials, as stated before, does not destroy the view.
The problem:
My problem comes when navigating to the Calculator view, the Report view is destroyed, which then destroys my School view. I do not want to also use queryParams to replace my Report views.
The reason I need to make sure the views aren't destroyed is because I have a select box with 3,000 schools in my School partial. It takes too long to re-render this. It would be a much better UX to simply show/hide the Report views.
Don't fight with Ember. You will lose.
Views are instantiated and rendered when needed and torn down when done.
Why do you have a 3000-element dropdown, anyway?
If you really, really want to do this, what I would suggest is putting a {{render}} on your application page, and hide it. The view will be created and rendered when the app comes up and persist as long as the app is alive. Then, in the didInsertElement of your view, do a cloneNode of that hidden element and insert it into the view's DOM somewhere. You may have to muck around getting event handlers wired up correctly.
My suggestion is not using "render" but using "partial", so you only need to drop in the template that you want. Have a control variable that set show/hide via css class. And control that variable using you controllers.
Using "partial" will allow you to have school template independent from report, thereby removing report will not affect school.
Just make sure you define the outlet and partial correctly.
Hope it helps!

What is the ember way to add popovers to views?

I'm working on a events board app. Events are displayed in columns at the height matching the start time and pack into the space if there is more then one overlapping. Each event is a view and I want to have a div next to the view that shows and hides on hover.
I know how to bind to mouseEnter and mouseLeave to show and hide part of the template but I want to show something adjacent to my view/template not within it.
I've already got some computed properties on the view to place the event with the correct height and width so I don't want to add the popover inside the view.
Here is something to mess with http://jsbin.com/osoner/1/edit
Seems like something simple but I want to make sure I'm doing things the Ember way.
After messing a little with your provided jsbin, here the results.
Basically what I've done was adding a new popup css declaration wich do position the popup so that it appears outside the parent view, and also moved the {{#if...}} helper into the originating view.
If you want to go more fancy, checkout this jsfiddle wich uses the twitter boostrap popover.
Hope it helps.

Is there a way to tell when a computed property has been inserted in the DOM with Ember?

I have a computed property that acts as formatter. Example fiddle to show basic functionality here
, http://jsfiddle.net/mlienau/xSkyd/2/.
I haven't implemented this functionality in the example, but the end user of this can remove terms by dragging them out, using draggable from jquery-ui . I was accomplishing this using a jquery live on mouseover of the element, but on ipad it doesn't work. Adding touchstart to live event is a hack because the user has to touch it once, before they can drag it out.
So my main question is: Is there a way to determine when a computed property has been inserted into the DOM like there is with view and didInsertElement, so I can set up the draggable handle there? Also, I am aware of some non-ideal ember practices in the example. Thanks!

Ember-table: fails when used in a hidden div (workarounds welcome!)

I'm trying to use ember-table inside a Bootstrap tab, but apparently if the table is contained in a tab that is initially display: none, the table layout doesn't work: everything is mis-sized and stuck in the upper-left of the table container.
I've narrowed the problem down by making a manually display-toggled div and it exhibits the same behavior.
I have a couple of ideas of how to workaround this, but I'm interested in others' ideas.
Also, should I file this as a bug? Seems like a common use case.
You can resize the table when you open the tab.
this.get('tableController').set('_width',820);
I had a similar situation, albeit not exactly the same. I initially show the ember-table component in a 'light' view, with one width, but the user can toggle between that and a 'full' view, with a larger width (as implied by its container). The toggle to larger width would size the container correctly but the portion of the ember-table not visible in the light view would contain only blank space, not cell contents nor borders, nor column headers. It's as if it never re-rendered after the container's dimensions changed.
The solution I found was to force a re-render of the table manually on the basis of an external property I would change when this light/full mode was toggled by the user. To achieve this, I extended the table component as shown:
export default Ember.Table.EmberTableComponent.extend({
// exposes a hook to resize (i.e. rerender) the table when it would otherwise
// not have been detected
resizeTriggered: function() {
this.handleWindowResize();
}.observes('resizeTrigger')
});
Since I'm using ember-cli, I saved the above under components/my-table-component.js.
Having done this, I would then include the table in my template like this:
{{my-table-component
columnsBinding="columns"
contentBinding="content"
resizeTrigger=resizeTriggerProperty
}}
Now, I simply update the controller's resizeTriggerProperty to any (new) value every time I want to ensure that the table re-renders. In my case, I would set it in the course of an action (e.g. MyRouteController):
actions: {
triggerResize: function() {
this.set('resizeTriggerProperty', new Date().getTime());
}
}
This may be a little late, but I am using Ember Table 0.4.1 (latest), and I found that ember table redraws on window resizes, so I used this to make the tab show the table when the tab changes:
$(window).resize();
and this did the trick, ember table redraws itself whenever I change the tab.