有许多问题以这样或那样的方式提出:"在呈现视图的某些部分之后我该怎么做?" (这里,这里,这里只是为了给几个).答案通常是:
didInsertElement在最初呈现视图时运行代码.Ember.run.next(...)运行代码,如果需要访问创建的DOM元素.isLoaded后,使用观察者或类似属性执行某些操作.令人恼火的是,这导致了一些非常笨拙的样子:
didInsertElement: function(){
content.on('didLoad', function(){
Ember.run.next(function(){
// now finally do my stuff
});
});
}
Run Code Online (Sandbox Code Playgroud)
当你使用ember-data时,这实际上并不一定有用,因为isLoaded可能已经是真的(如果记录之前已经加载过,并且不再从服务器请求).因此,正确排序是很困难的.
最重要的是,您可能已经在视图模板中观看isLoaded,如下所示:
{{#if content.isLoaded}}
<input type="text" id="myTypeahead" data-provide="typeahead">
{{else}}
<div>Loading data...</div>
{{/if}}
Run Code Online (Sandbox Code Playgroud)
并在您的控制器中再次执行它似乎是重复.
我提出了一个有点新颖的解决方案,但它要么需要工作,要么实际上是一个坏主意......任何一种情况都可能是真的:
我写了一个小的Handlebars帮助器{{fire}},当执行包含的把手模板时会触发一个带有自定义名称的事件(即应该每次重新渲染子视图时,对吗?).
这是我很早期的尝试:
Ember.Handlebars.registerHelper('fire', function (evtName, options) {
if (typeof this[evtName] == 'function') {
var context = this;
Ember.run.next(function () {
context[evtName].apply(context, options); …Run Code Online (Sandbox Code Playgroud) 这个问题表明,覆盖Ember.View实例didInsertElement允许您在视图的元素位于DOM之后执行一些代码.
当然,didInsertElement在添加到Ember.CollectionView的子视图类上覆盖将在渲染和插入每个子视图后运行钩子.
Ember.CollectionView上有两个面向集合的钩子,arrayDidChange并且contentDidChange在底层内容发生变化后执行,但它们在任何渲染发生之前执行.arrayDidChange对添加到数组的每个元素执行,并contentDidChange包装内容绑定.
我希望能够钩住渲染管道,类似于willInsertCollection和didInsertCollection,在渲染所有子元素之前和之后操纵DOM - 基本上,在过滤器之前和之后contentBinding.
有任何想法吗?我很难过.
我无法在任何地方找到此文档或在任何问题中回答.唯一确定存在的是"点击"(通过处理带动作的事件).
我见过的相关问题(不回答我的问题):
在我的Ember应用程序中,如何跳转到我的Handlebars模板中的HTML锚点?我创建了一个jsFiddle,显示了我想要完成的任务.
背景
Ember通过应用程序导航的模型使用HTML锚点.
我有以下要求:当用户点击Handlebar linkTo助手导航到新的路线目的地时,浏览器应自动滚动到与该新路线目的地相关联的Handlebars模板内的锚点.
我使用JWPlayer在我的网站上显示视频,JWPlayer使用javascript创建查看器.
我的隐藏视图更改显示后,我必须运行JWPlayer脚本.
jwplayer('video_space').setup({
'flashplayer': 'player.swf',
'file': 'http://content.longtailvideo.com/videos/flvplayer.flv',
'controlbar': 'bottom',
'width': '470',
'height': '320'
});
Run Code Online (Sandbox Code Playgroud)
我将我的视图与控制器上的值绑定
<script type="text/x-handlebars" >
{{#view Food.previewView }}
Video session
<div {{bindAttr class="showPreview"}}>
<div id='video_space'>Video Loading...</div>
</div>
{{#view SC.Button target="Food.appController" action="show"}}
show
{{/view}}
{{/view}}
</script>
Run Code Online (Sandbox Code Playgroud)
我的javascript为所有控制器和视图
Food = Ember.Application.create();
Food.appController = Ember.Object.create({
showVideo: false,
show: function(){
Food.previewView.set('showVideo', true);
}
});
Food.previewView = Ember.View.extend({
showVideoBinding: 'Food.appController.showVideo',
showPreview: function() {
return this.get('showVideo') ? "show" : "hide";
}.property('showVideo')
});
Run Code Online (Sandbox Code Playgroud)
如果我在更改"showVideo"变量时运行JWPlayer脚本,视频将会出错,因为$('#video_space')仍然是隐藏的.
Emberjs有一些委托方法,如"afterViewChange"或"viewDidChange"?
我正在编写一个Ember.js应用程序,我希望在视图渲染后立即在div一个类上运行以下Javascript代码navbar:
$('.navbar').affix({offset: -1000});
Run Code Online (Sandbox Code Playgroud)
我不知道在Ember中可以轻松地做到这一点,因为标准的JQuery $(document).ready()不能与Ember应用程序一起使用.必须有一些简单的方法来做到这一点,但这个问题的所有其他答案似乎都是复杂的解决方法,并且基于过时的Ember.js版本.
问题模板:
<script type="text/x-handlebars">
<div class="navbar" data-spy="affix">
<div class="navbar-inner">
<div class="container">
<a class="btn btn-navbar">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</a>
</div>
</div>
</div>
{{outlet}}
</script>
Run Code Online (Sandbox Code Playgroud) 我正在尝试将一个正在运行的谷歌图表示例集成到我的ember.js应用程序中.问题是,我不确定将drawChart()函数放在何处,以便仅在页面上的目标DOM元素运行时才运行.
我认为加载函数的正确位置在视图中(我没有看到任何理由将它放在模型/控制器/路由中).但我需要确保drawChart()在模板完成渲染并且<div id='chart'>元素存在之后才会调用.
显然View.init()太早了. 我应该在哪里调用我的构建函数?
它甚至属于一个视图(也许我应该使用控件或把手助手吗?)
App.DashboardView = Ember.View.extend({
name: "",
init: function(){
// this breaks the app...
//google.load("visualization", "1", {packages:["corechart"]});
//google.setOnLoadCallback(drawBarGraph);
this.set('name', 'ted');
return this._super();
}
});
Run Code Online (Sandbox Code Playgroud) javascript model-view-controller google-visualization ember.js