文章来源:
Ember2.0
不再支持直接在模板中使用script
标签,也就是说不能在模板中直接插入script
代码段了!官方的建议是尽可能把所有的js代码都放在app/index.html
中。但是实际项目中可能会遇到这样的问题:
实现方式一
在某个子模板中使用jQuery方法为某个元素增加了单击的监听事件,比如下面的代码:
$(function() { $("#elemId").click(function() { // 处理 });});
当你通过link-to
进入到此子模板(比如:)的时候上述的监听代码并不能有效触发,因为进入模板的时候并不会刷新页面,Ember只是把元素插入到{ {outlet}}
占位符位置上(可以想象成是使用js动态添加HTML标签到某个元素上)。但是进入子模板后你手动刷新当前页面后上述的js代码却能有效触发!
可见通过link-to
进入的页面并不会重新加载页面,那么如何解决呢?在2.0
版本之前很容就能解决这个问题——直接把js代码放到子模板最后就行了,但是2.0
版本之后不支持直接使用script
标签了!但是要解决这个问题也仍然是很简单的,可以使用组件实现。下面创建一个组件专门用于插入JavaScript代码到模板中。
// app/components/script-tag.jsimport Ember from 'ember';// ember2.0之后不支持在模板中使用script标签,// 通过组件方式加入export default Ember.Component.extend({ tagName: 'script', attributeBindings: ['type'], type: 'text/javascript'});
有了组件之后调用就组件插入JavaScript代码就很方便了,并且2.0
版本及更高版本也是支持的。下面请看如何调用:
{ {! 调用组件插入JavaScript代码}}{ {#script-tag}}$(function() { $("#elemId").click(function() { // 处理 });});{ {/script-tag}}
这样处理之后完美解决了通过link-to
进入子模板不触发js事件的问题。 这种方式是可以解决了不加载js代码的问题,但是这种方式显然是不好的,既然官方都不允许开发者在模板中使用script
标签了,我们也没必要再这样做了,那么有什么更好的方法呢?请看方法二。
实现方式二
首先谢谢的建议,之前一直没关注到使用组件生命周期方法去实现。这种方式才是官方所推荐的。那么如何实现了,其实很简单,我们只需要把需要在模板上加载的代码放到方法didInsertElement()
中即可。详细请看。下面做一个简单的示例。
模板
测试如何在进入本模板的时候加载js代码。第一种方式是把JavaScript脚本放到一个组件中加载
参考http://blog.ddlisting.com/2016/05/16/use-script-tag-in-template/
第二种方式是把JavaScript脚本放在组件的didInsertElement()方法中加载
比如为按钮增加jQuery事件监听。
把触发事件的代码放在app/index.html
UeditorTest { {content-for "head"}} { {content-for "head-footer"}} { {content-for "body"}} { {content-for "body-footer"}}
在主模板增加一个进入子模板的链接
{ {! app/templates/application.hbs }}{ {#link-to 'script'}}进入子路由script{ {/link-to}}
等待项目重启完毕,点击首页的链接进入子模板app/templates/script.hbs
。然后点击按钮,可以发现并没有触发JavaScript事件。手动刷新页面,再点击按钮,可以看到JavaScript事件被触发了!这是本文一开始就说的问题。现在我们把index.html
里的JavaScript代码移动到组件中。但是方法didInsertElement()
是在组件类中才有的,所以我们需要创建一个组件。
ember g component script-tag2
组件创建完毕之后我们把原来子模板script.hbs
的代码移动到组件模板app/templates/components/script-tag2.hbs
中,然后子啊子模板script.hbs
中调用组件。
{ {! app/templates/script.hbs}}{ {script-tag2}}
关键的部分如何在组件类中触发JavaScript事件呢? 直接把放在index.html
中的JavaScript代码移动到方法didInsertElement()
中,然后去掉外层的$(function(){})
。然后修改成ember的方式调用Ember.$
,当然直接使用$("#xxx")
的方式也是可以的。
// app/components/script-tag2.jsimport Ember from 'ember';export default Ember.Component.extend({ didInsertElement() { Ember.$("#alterSometing").click(function() { alert("单击了按钮。此方法是在组件类的!!"); }); }});
等待项目重启完毕,从新从首页点击链接进入子模板,然后再点击按钮。可以看到JavaScript事件成功触发。截图如下:
同理,其他的JavaScript事件也是同样的方法。
以上两种方式都可以解决进入子路由不加载JavaScript的问题。方法二是官方建议的,组件在ember中越来越重要的。为了能与新版ember兼容最好还是使用第二种方法。
如果你有更好的方法欢迎给我留言建议!
再次感谢。