Is there a callback in ember.js which I can use to run code after all views are rendered after state transition?

淺唱寂寞╮ 提交于 2019-12-06 05:52:39

问题


I've got application view consisting of three outlets:

<script type="text/x-handlebars" data-template-name="application">
        {{outlet header}}
        {{outlet content}}
        {{outlet footer}}
</script>

which render their own views (simplified):

<script type="text/x-handlebars" data-template-name="header">
<a href="#" data-role="button" data-icon="arrow-l" data-iconpos="notext" 
        {{action changeDate view.prevDate href=true}}>Prev</a>
{{view.model.weekDay}}
<a href="#" data-role="button" data-icon="arrow-r" data-iconpos="notext" 
        {{action changeDate view.nextDate href=true}}>Next</a>
</script>

<script type="text/x-handlebars" data-template-name="content">
{{view.model.month}}
</script>

<script type="text/x-handlebars" data-template-name="footer">
{{view.model.day}}
</script>

and application router which refreshes the views using routing logic

Router: ember.Router.extend({
    root: ember.Route.extend({
        changeDate: ember.State.transitionTo('date'),
        index: ember.Route.extend({
            route: '/',
            connectOutlets: function (router) {
                router.transitionTo('date', new Date());
            }
        }),
        date: ember.Route.extend({
            route: '/:date',
            serialize: function (router, date) {
                return { date: toUrlString(date) };
            },
            deserialize: function (router, param) {
                return parseUrlString(param.date);
            },
            connectOutlets: function (router, date) {
                var appController = router.get('applicationController'),
                    controller = router.get('dayController');
                controller.navigateTo(date || new Date());
                appController.connectOutlet({ outletName: 'header', viewClass: router.namespace.HeaderView, controller: controller });
                appController.connectOutlet({ outletName: 'content', viewClass: router.namespace.ContentView, controller: controller });
                appController.connectOutlet({ outletName: 'footer', viewClass: router.namespace.FooterView, controller: controller });
            }
        })
    })
})

This all works fine except of one thing - the application uses jQuery Mobile, and after views re-rendered I need to apply jqm enhancements to the updated elements. I tried using didInsertElement callback in each view to enhance the part that has been redrawn. But it doesn't work as expected because jqm has very special treatment of the header and footer blocks. They are not properly enhanced unless all page is re-initialized either by using .trigger('pagecreate') or by using .page('destroy').page() on the root application view.

The issue is - each view calls its own didInsertElement, so the enhancement code executes three times.

Is there a reliable way to execute the enhancement code after route transition is finished and all affected views are rendered and updated with the current data?


回答1:


I recently added something that will help with this, an afterRender queue. See this commit, in particular the test for an example of usage.



来源:https://stackoverflow.com/questions/13293992/is-there-a-callback-in-ember-js-which-i-can-use-to-run-code-after-all-views-are

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!