【问题标题】:Ember - Resize DIV on load, transition and resize?Ember - 在加载、转换和调整大小时调整 DIV 大小?
【发布时间】:2015-05-11 21:29:43
【问题描述】:

我正在构建一个 Ember 应用程序,该应用程序需要在加载应用程序时将容器 DIV 的大小调整为完整的窗口高度,然后在转换到新路由时再次运行相同的调整大小功能,然后在调整窗口大小时也运行。

在普通网站上,我会这样做:

var appUI = {
    init: function(){
        appUI.sizeContainer();
    },

    sizeContainer: function(){
        var winHeight = jQuery(window).height();
        jQuery('#container').height(winHeight);
    },

    onResize: function() {
        appUI.sizeContainer();      
    }
}
jQuery(document).ready(function($){
    appUI.init();

    jQuery(window).resize(function(){
        appUI.onResize();
    });
});

但显然这在 Ember 中不起作用。

这不能是一个组件,因为#container DIV 包装了整个当前视图。但是随着 Ember 远离视图,我应该怎么做呢?

我想出的唯一方法是使用视图,并连接到didInsertElement,但我不知道如何在不必为每条路线创建 view.js 文件的情况下做到这一点,其中包含相同的调整大小代码?那么调整大小事件呢?我认为应用程序视图didInsertElement 可能适用于此,但它只在加载时运行一次。

我所有的路线模板基本上都遵循这个模式:

{{top-header}}

{{background-image image=backgroundImage}}

{{side-menu session=session menuOpen=menuOpen}}

<div id="container" class="vert-center route-name"> 

    {{partial "_logo"}}         

    {{some-component}}

</div>

【问题讨论】:

  • 什么是livinUI?如果我理解正确,您想在应用加载、新路由加载或窗口大小调整时调用 sizeContainer 函数?您的所有模板(对于每条路线)是否都在 #container 内,还是需要动态设置此 ID?
  • @nem 我更新了问题以显示模板示例。我用 var 修正了错字,它应该是 appUI。是的,我想要一个函数在加载、新路由和调整大小时运行(但也许有比我想知道的更多的 Ember 方式)。 #container 不是动态的,它存在于每个模板中。

标签: javascript jquery ember.js resize


【解决方案1】:

在加载应用程序和window 时调整大小几乎可以按照您描述的方式完成。

一种简单的方法是覆盖ApplicationRoute 内的renderTemplate 挂钩。在这个钩子中,您可以渲染您的应用程序模板,然后在 window 对象上初始化 resize 侦听器:

// handles on document load and on window change events
App.ApplicationRoute = Ember.Route.extend({
    renderTemplate: function(controller, model) {
        this.render('application');             // render the application template
        appUI.init();                           // call the init event on application load
        Ember.$(window).resize(function() {     // setup resize listener on the window object that will be called when window resizes
            appUI.onResize();
        });
    }
});

至于每次加载路由时调整大小,您可以实现一个通用的Ember.Route,例如,我们称之为ResizableRoute,它在其模板渲染后调用appUI.resize()。这可以通过覆盖renderTemplate 钩子再次实现。

// calls onResize() each time the current route's template is rendered in the DOM
App.ResizableRoute = Ember.Route.extend({
    renderTemplate: function() {
        // render the template with the same name as the route (assumes you follow ember naming conventions)
        this.render(this.routeName); 
        // call resize since the route is loaded         
        appUI.onResize();
    } 
});

现在您可以让任何其他路由扩展此ResizableRoute,并且每次渲染该路由的模板时,都会调用appUI.onResize()

App.AnyOtherRoute = App.ResizableRoute.extend({
    // do other stuff
});

所有调用都在 AFTER 渲染模板的原因是因为#container 元素肯定已经插入到 DOM 中并且可以使用 jQuery 抓取。

Here is a running jsFiddle example


编辑

除了覆盖renderTemplate 钩子之外,您可以实现此目的的另一种方法是创建一个ResizeUIComponent,它将在每次加载您的路线时执行调整大小。缺陷是你必须记住将这个组件插入到每个路由的模板中。

App.ResizeUIComponent = Ember.Component.extend({

    didInsertElement: function() {
        this.$().hide();   // make the component invisible, probably better to do it with css but this is a quick example
        appUI.onResize();
    }

});

并将此组件添加到您希望在每次加载时调用onResize() 的所有模板(包括应用程序):

{{top-header}}

{{background-image image=backgroundImage}}

{{side-menu session=session menuOpen=menuOpen}}

<div id="container" class="vert-center route-name"> 

    {{resize-ui}}  {{!-- add the invisible resize component as the child of #container to ensure necessary rendering order --}}    

    {{partial "_logo"}}         

    {{some-component}}

</div>

您可以在ApplicationControllerinit 事件之后在window 对象上添加一个监听器:

App.ApplicationController = Ember.Controller.extend({
    onInit: function() {
        Ember.$(window).resize(function() {     // setup resize listener on the window object that will be called when window resizes
            appUI.onResize();
        });
    }.on('init');
});

【讨论】:

  • 这看起来很有趣。你认为它如何与 Ember 2.0 路线图配合使用?他们说要远离render()gist.github.com/samselikoff/1d7300ce59d216fdaf97
  • 是的,但在这种情况下,这是必要的。您需要等待路由的模板被渲染,然后才能获取其中的#container,因此您必须覆盖renderTemplate 挂钩并在调整UI 大小之前先渲染模板。从本质上讲,您需要确保元素在 之前在 DOM 中,然后再尝试抓取它。至于 Ember 2.0,它在链接中说“控制器/模板对最终将成为可路由的组件。”此时您将能够使用组件的didInsertElement 作为挂钩模板渲染后调用。
  • 另一种方法是使用视图,这对于 Ember 2.0 来说更不是面向未来...
  • 谢谢@nem。我怀疑未来视图可能比这种基于路由的渲染方式更容易移植到新组件。我在使用 #container 时也遇到了问题(因为 IRL 我使用的是液体火,并且一次在 DOM 中有两个 #container
  • 这个新的组件调整器可能会更好。我可以把它放在我的 application.hbs 文件或 index.html 中,所以它都在一个地方。但是,如果调用了组件didInsertElement 钩子,是否意味着存在container?我认为组件的范围非常有限。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-13
相关资源
最近更新 更多