Ember 2.0/2.10 trigger script after Ready


#1

Hello all!
I’m new to ember. But really search everywhere.
I find information only for old versions, like 1.10, 1.30. But now use 2.10 (can downgrade to 2.0).
I have got my own script - autosize and autoindent rows in big list, for responsive design.

I need someway to trigger my function. Like in $(document).ready(function () {})
The problem is with browsers “back” button.
So, let it be smartColumns(); function


THIS TRIGGERS BEFORE TEMPLATE IS FULLY LOAD

in Controller:

trigger: function() {
    Ember.run.scheduleOnce('afterRender', this, function() {
       smartColumns();
    });
  }.on('init')

in Routes:

afterModel: function() {
  smartColumns();
}

clear js:

window.onpopstate = function() {
	smartColumns();
};

THIS NOT WORKING WITH BROWSERS “BACK” BUTTON

$(window).on('hashchange', function() {
    smartColumns();
});

window.onhashchange = function() {
    smartColumns();
};

$(document).ready(function () {} not working with “back” button too

$(document).ready(function () {
    smartColumns();
});

I can use controller or route. NO components.

Tell me please, how can trigger my function after content is fully load?


#2

Why can’t you use a component?

It sounds like smartColumns(); is a function that is doing javascript based layout. If that’s true, this type of work should be done in an Ember.Component (historically in an Ember.View) because they have lifecycle hooks that go along with DOM elements being rendered.

It’s hard to put together an exact example without knowing more about your use case. But I would typically do something like this:

// apps/components/row-item-list.js
import Ember from 'ember';

export default Ember.Component.extend({
  listItems: null,
  
  // Setup the initial smartColumns
  _setupSmartColumns: Ember.on('didInsertElement', function() {
    window.smartColumns.setup(this.$('.smart-column-wrapper'));
  }),

  // Observe listItems and use `run.once` to coalesce updates
  _triggerSmartColumns: Ember.observes('listItems.[]', function() {
    Ember.run.once(this, this._scheduleSmartColumns);
  }),
 
  // Update smartColumns after the next render.
  _scheduleSmartColumns: function() {
    Ember.run.schedule('afterRender', () => {
      window.smartColumns.update(this.$('.smart-column-wrapper'));
    });
  },

  // Tear down the smartColumns
  _cleanupSmartColumns: Ember.on('willDestroyElement', function() {
    window.smartColumns.destroy(this.$('.smart-column-wrapper'));
  })
});

#3

Why can you not use a component? This sounds like a silly requirement as you want to do something after rendering, and that sort of logic belongs in a component.


#4

workmanw, really thanks for helping!! The main thing that you write was (historically in an Ember.View) After this I understand all. And big thanks for the code!! I rewrite it, and it works!

import Ember from 'ember';
export default Ember.Component.extend({
  // Trigger smartColumns after render
  _triggerSmartColumns: Ember.on('didInsertElement', function() {
    smartColumns();
  })
});

workmanw, jasonmit it’s very hard for me to understand - why I need to put all my code to component, instead that I can do everything (but not trigger script after render) in template. Controller api has got “afterModel”, why it’s hard to add “afterRender”? It’s very simple.

I know that later Ember dev team will remove controllers. But I don’t ever read anywhere about templates. For sure, as I understand now - you can do everything in components and use templates only for trigger this components.

And one more thing for me hard to understand - why Ember dev team use “Components” instead of “Views” and why we need to compile model in router?
I love MVC in PHP. Model you can get in model files, view in view files, and use controller to change model or connect model with view.
Why not to use this style in Ember? Why we can’t get and push lines to “DATA” in model. Why we need templates if we use components?


#5

You can learn a bit more about the thought processes behind deprecating controllers in the RFC here: https://github.com/emberjs/rfcs/blob/master/text/0015-the-road-to-ember-2-0.md

Then, Ember’s version of MVC is completely different to what you know about backend MVC. I suggest you have a look at the Rock & Roll With Ember ebook - it’s an awesome resource to get started with Ember.


#6

constantm, Great Thanks for the article. If I find it earlier I think I wouldn’t ask this questions.

I find and buy that book yesterday. For first pages I start to love it.
But first I need to finish my project as soon as possible. And only two things stops me - the problem above that I solve with workmanw help and problem with count models, getting url hash and do next/prev arrows in Component. But I think now, I will solve it.


#7

Glad you got were able to get it working. :slight_smile:


#8

workmanw, One more time - thank you so much!!

Maybe you help me with small thing one more time? :blush:
Only one problem remains - how to get model in compoment.js

Inside

Ember.Component.extend({

})

Or maybe another cool way to do my thing =)


So, I want to make arrows (prev/next) that will cycle all my items(every item on single page), page by page. Arrows will be in top-bar component, it renders in application template in follows all the pages. And only on items pages it will have arrows. What I think about it:

  1. I can get url in top-bar component by - window.location.pathname.split("/").slice(-1)[0]

  2. If it returns empty, then for my project it will be home page (I can locate last path of url by different scripts, but I prefer this one)

  3. So if returns empty, then nothing to do. Top-bar renders without arrows.

  4. In application route, I call json file and push it to the story, to “application”, and returns count of pushed items.

  5. I render top-bar

     {{top-bar count=model}}
    

It pull count to top-bar.hbs. How can I take value of this count in top-bar.js component?
6. When I will get count in top-bar.js, I will make urls in pull it to top-bar.hbs on every page rendering.

One more time, problem is - how to get model in compoment.js?


#9

Ohh. It was simplest way. I really tired with ember, but as much I know it, as much greater it for me.

So, to pickup count in component.js: just simply

this.get('count')

inside the function

I use this for check (you can do your own way):

didInsertElement: function() {
    console.log(this.get('count'));
}