渲染ember模板后执行action(javascript函数)

时间:2015-05-13 15:45:32

标签: javascript ember.js

我有一个非常小的带有emberjs的网页,我想在其中显示一些项目列表和openlayers地图,以及所选项目的另一个地图。 这样的事情:

<script type="text/x-handlebars" id="list">
<div class="list">
    <div id="list_map"></div>
</div>
{{outlet}}
</script>

<script type="text/x-handlebars" id="list/item" >
<div class="item">
    <div id="item_map"></div>
</div>
</script>
<script>
function showListMap() {
    listMap = new ol.Map({target:'list_map'});
}
function showItemMap() {
    itemMap = new ol.Map({target:'item_map'});
}
</script>

显示列表地图没有问题:

model: function(params) {
        var content = [];
        var url = 'http://localhost:8080/app/list'; 
        $.ajax({
          url: url,
          success: function(surveys) {            
            content.pushObjects(surveys);
            showListMap();
          }
        });
        return content;
}

并且我在项目控制器中执行了操作,当打开所选项目时,但是如果我尝试在那里创建项目映射(在控制器操作中)它失败(afaik,因为在DOM中当时没有这样的div)。 因此,如果我可以在div已添加到DOM后执行操作或我的函数,它应该可以工作。 问题是,如何在将模板添加到DOM之后执行某些操作,或者执行此类操作的方式完全错误(比使用正确的ember方式)?

2 个答案:

答案 0 :(得分:3)

看到完整的代码,我无法说些什么。但是要在呈现DOM之后执行一些代码,您需要在run loops afterRender队列上安排一个函数。

Ember.run.scheduleOnce('afterRender', this, function() {
  //The div should be available now.
});

但是如果你真的需要触摸DOM,我建议你将地图代码包装在一个组件中。组件获得didInsertElement,您可以在其中编写地图初始化代码。

var component = Em.Component.extend({
  setup: function() {
    //Do you map init here.
  }.on('didInsertElement')
});

答案 1 :(得分:0)

不幸的是,没有一个真正好的路由或控制器钩子在页面已经呈现后触发。我相信这是因为 Ember 的开发者认为直接与 DOM 对话是一种反模式。

话虽如此,我认为它有时对于静态网页上的复杂 UI 非常方便。如果您想在路由呈现后执行某种 jquery 或使用 DOM API,您可以在路由文件中执行以下操作(正如@Dainius 正确指出的那样)

路由名称.js

import Route from '@ember/routing/route'; 
import jQuery from 'jquery';

export default class myRouteFile extends Route {

  manipulateDom = function() {
     $("#myDiv").css( "color", "red" );
  }

  init() {
    this._super(...arguments)
    Ember.run.scheduleOnce('afterRender', this, this.manipulateDom)
  }
}