因项目需要前端展示中采用了ace editor组件用来编辑sql语句.在新建页面在vue的mounted方法中初始化editor组件.妥妥完成相关功能.代码如下:
mounted: function () {
editor = ace.edit("editor");
//editor.setTheme("ace/theme/twilight");
editor.setTheme("ace/theme/sqlserver");
editor.session.setMode("ace/mode/sql");
editor.renderer.setScrollMargin(10, 10);
editor.setOptions({
// "scrollPastEnd": 0.8,
autoScrollEditorIntoView: true
});
},
在需要获取sql的相关js中调用下述方法即可取得编辑框内的sql:
this.sql = editor.getValue();
相关的HTML代码段
<div class="form-group">
<label class="col-sm-2 control-label">Sql语句</label>
<div class="col-sm-10" style="height: 250px;">
<div id="editor"></div>
</div>
</div>
vue的数据定义段
var app = new Vue({
el: '#app',
data: {
dsId:'',
sql : 'select * from',
editor: null,
},
....
});
至此一切OK.
然而由于该编辑的效果实在是太风骚了以致于我想在展示页面也采用该组件来显示sql.依照通常的写法.我在vue created方法中通过Ajax异步获取了对应的sql语句.并设置vue 数据 sql为该值,然而并没有什么卵用(其实仔细想想就知道行不通,因为没有对应的v-model实现双向绑定).在created调用editor.setVaule();报对象不存在(created执行时editor对象可能还没完成创建).
只好在c方法中调用editor.setValue(app.sql).好消息是编辑器的值被成功初始化了,坏消息是初始化的内容不正确,居然是model的原始值(selelct * from).
仔细分析一下原因,在created中执行的数据获取ajax是异步执行,虽然在 vue的周期周期中created是先于mounted执行的.但是也不能保证异步执行完了才会进行mounted.很显然在这里异步的ajax还没执行完,mounted已经执行结束了.貌似原因找到了.那么怎么办呢?异步不行上同步.说干就干啊.
created: function () {
var obj = this;
$.ajax({
type: "GET",
async:false,
data : {
dtId : this.dtId,
},
url: '${ctx}/XXX/getInfo.do',
success: function(dat){
obj.dtName = dat.dtName;
var dataSetInfo = dat.dtSetInfo;
obj.sql = dataSetInfo.dtSql;
var megerKeyHtml = template('TemplateMergeKeyInfo2',dat);
$("#mergekey").html(megerKeyHtml)
}
});
},
同步代码果然强大问题妥妥解决了.解决了.然而如果页面只有这一个编辑器的话问题确实也可以这样解决.然而为了处理一些简单的html拼接我还映入了 template-web.js(为啥不用vue的模板?因为这个更简单啊!).然后就在我把这个ajax 改成同步以后
var megerKeyHtml = template('TemplateMergeKeyInfo',dat);
$("#mergekey").html(megerKeyHtml)
这两行代码又不能执行了.总是报下面这个错啊.
让我误以为我的模板数据定义出现了问题.
多番核对后我确定应该是同步执行的问题.很有可能在执行create方法的时候模板没有被加载完成(后续确认)?由此可见在created方法内对第三方组件进行操作存在不确定的问题(组件不一定能正确加载).貌似我走进了死胡同,一个要同步一个要异步,难道我要写两个请求去处理页面初始化?
后来所有的功能被移入mounted功能且仍旧是异步执行.一切都恢复OK了.
mounted: function () {
editor = ace.edit("editor");
//editor.setTheme("ace/theme/twilight");
editor.setTheme("ace/theme/sqlserver");
editor.session.setMode("ace/mode/sql");
editor.renderer.setScrollMargin(10, 10);
editor.setOptions({
// "scrollPastEnd": 0.8,
autoScrollEditorIntoView: true
});
$.ajax({
type: "GET",
async:true,
data : {
dtId : this.dtId,
},
url: '${ctx}/XXX/getInfo.do',
success: function(data){
var dataSetInfo = data.dtSetInfo;
app.sql = dataSetInfo.dtSql;
var megerKeyHtml = template('TemplateMergeKeyInfo',data);
$("#mergekey").html(megerKeyHtml)
editor.setValue(app.sql);
}
});
},
那么在传统多页面应用, 使用vue 和其他第三方组件时,初始化应该优先考虑在mounted方法中进行.