Dojo _TemplatedMixin:更改模板字符串
Dojo _TemplatedMixin: changing templateString
如何在以后(不在构造函数中)使用 mixin dijit/_TemplatedMixin
和 dijit/_WidgetsInTemplateMixin
更改小部件的模板?
我的方案是小部件必须调用服务器以获取数据,然后回调函数会将数据与模板文件合并,然后生成的模板应用于 templateString
.此时小部件应更新其内容。
设置templateString 和调用buildRendering() 无效。
这是我的代码的简化版本:
define([
"dojo/_base/declare",
"dojo/_base/lang",
"dijit/_WidgetBase",
"dijit/_TemplatedMixin",
"dijit/_WidgetsInTemplateMixin",
],
function(declare, lang, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin) {
return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
constructor: function(id) {
this.id = id;
this.templateString = "<div>Loading...</div>";
//use xhr to call REST service to get data.
//dataLoadedCallback is executed with response data
...
},
dataLoadedCallback : function(data) {
this.destroyRendering();
//render a templateString using the data response from the rest call
this.templateString = "<div>Data is loaded. Name:" + data.name + "</div>"
this.buildRendering();
},
});
});
你不能做这样的事。该模板在 postCreate
方法之前仅被解析一次。
然而,您可以做的事情很少:
- 创建一个非ui 小部件,它将执行 XHR 调用。当此非 ui 小部件获得 XHR 响应时,它会创建具有正确
templateString
的 UI 小部件
- 或使用
dojo/dom-construct
。它包含一个 toDom
方法,可用于将字符串转换为节点。然后您可以将其附加到小部件。
注意:这不会解析任何 data-dojo
属性
也可以直接将接收到的templateString注入到widget的domNode中:
dataLoadedCallback : function(data) {
this.domNode.innerHTML = "<div>Data is loaded. Name:" + data.name + "</div>";
//you might be able to parse the content (if you have subwidgets) using dojo/parse
},
最后但同样重要的是,这是我为自己编写的一个实用程序。它允许在任何时候解析任何 templateString
(就像 dojo 在创建小部件时所做的那样)
define([
'dojo/dom-construct',
'dojo/string',
'dijit/_AttachMixin',
'dijit/_TemplatedMixin'
], function(domConstruct, string,
_AttachMixin, _TemplatedMixin) {
// summary:
// provide an utility to parse a template a runtime (and create attach point, atach events, etc...)
// Copyright: Benjamin Santalucia
var GET_ATTRIBUTE_FUNCTION = function(n, p) { return n.getAttribute(p); },
_TemplateParserMixin = function() {};
_TemplateParserMixin.prototype = {
parseTemplate: function(template, data, container, position, transformer) {
// summary:
// parse the template exactly as dojo will nativly do with a templateString
if(this._attachPoints === undefined) {
this._attachPoints = [];
}
if(this._attachEvents === undefined) {
this._attachEvents = [];
}
var nodes,
x,
len,
newTemplate = string.substitute(template, data, transformer),
node = domConstruct.toDom(_TemplatedMixin.prototype._stringRepl.call(this, newTemplate));
if(node.nodeName === '#document-fragment') {
node = node.firstChild;
}
//parse all nodes and create attach points and attach events
nodes = node.getElementsByTagName('*');
len = nodes.length;
for(x = -1; x < len; x++) {
_AttachMixin.prototype._processTemplateNode.call(this, x < 0 ? node : nodes[x], GET_ATTRIBUTE_FUNCTION, _AttachMixin.prototype._attach);
}
if(container) {
domConstruct.place(node, container, position);
}
return node;
}
};
return _TemplateParserMixin;
});
用法是:
returnedNode = w.parseTemplate(newTemplateString, {
templatePlaceHolderName: 'foo' //for teplate with placeholders like ${templatePlaceHolderName}
}, domNodeToInsertIn, 'only'); //last parameter is same as dojo/dom-construct::place() >> last, first, before, after, only
如何在以后(不在构造函数中)使用 mixin dijit/_TemplatedMixin
和 dijit/_WidgetsInTemplateMixin
更改小部件的模板?
我的方案是小部件必须调用服务器以获取数据,然后回调函数会将数据与模板文件合并,然后生成的模板应用于 templateString
.此时小部件应更新其内容。
设置templateString 和调用buildRendering() 无效。 这是我的代码的简化版本:
define([
"dojo/_base/declare",
"dojo/_base/lang",
"dijit/_WidgetBase",
"dijit/_TemplatedMixin",
"dijit/_WidgetsInTemplateMixin",
],
function(declare, lang, _WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin) {
return declare([_WidgetBase, _TemplatedMixin, _WidgetsInTemplateMixin], {
constructor: function(id) {
this.id = id;
this.templateString = "<div>Loading...</div>";
//use xhr to call REST service to get data.
//dataLoadedCallback is executed with response data
...
},
dataLoadedCallback : function(data) {
this.destroyRendering();
//render a templateString using the data response from the rest call
this.templateString = "<div>Data is loaded. Name:" + data.name + "</div>"
this.buildRendering();
},
});
});
你不能做这样的事。该模板在 postCreate
方法之前仅被解析一次。
然而,您可以做的事情很少:
- 创建一个非ui 小部件,它将执行 XHR 调用。当此非 ui 小部件获得 XHR 响应时,它会创建具有正确
templateString
的 UI 小部件
- 或使用
dojo/dom-construct
。它包含一个toDom
方法,可用于将字符串转换为节点。然后您可以将其附加到小部件。
注意:这不会解析任何data-dojo
属性 也可以直接将接收到的templateString注入到widget的domNode中:
dataLoadedCallback : function(data) { this.domNode.innerHTML = "<div>Data is loaded. Name:" + data.name + "</div>"; //you might be able to parse the content (if you have subwidgets) using dojo/parse },
最后但同样重要的是,这是我为自己编写的一个实用程序。它允许在任何时候解析任何 templateString
(就像 dojo 在创建小部件时所做的那样)
define([
'dojo/dom-construct',
'dojo/string',
'dijit/_AttachMixin',
'dijit/_TemplatedMixin'
], function(domConstruct, string,
_AttachMixin, _TemplatedMixin) {
// summary:
// provide an utility to parse a template a runtime (and create attach point, atach events, etc...)
// Copyright: Benjamin Santalucia
var GET_ATTRIBUTE_FUNCTION = function(n, p) { return n.getAttribute(p); },
_TemplateParserMixin = function() {};
_TemplateParserMixin.prototype = {
parseTemplate: function(template, data, container, position, transformer) {
// summary:
// parse the template exactly as dojo will nativly do with a templateString
if(this._attachPoints === undefined) {
this._attachPoints = [];
}
if(this._attachEvents === undefined) {
this._attachEvents = [];
}
var nodes,
x,
len,
newTemplate = string.substitute(template, data, transformer),
node = domConstruct.toDom(_TemplatedMixin.prototype._stringRepl.call(this, newTemplate));
if(node.nodeName === '#document-fragment') {
node = node.firstChild;
}
//parse all nodes and create attach points and attach events
nodes = node.getElementsByTagName('*');
len = nodes.length;
for(x = -1; x < len; x++) {
_AttachMixin.prototype._processTemplateNode.call(this, x < 0 ? node : nodes[x], GET_ATTRIBUTE_FUNCTION, _AttachMixin.prototype._attach);
}
if(container) {
domConstruct.place(node, container, position);
}
return node;
}
};
return _TemplateParserMixin;
});
用法是:
returnedNode = w.parseTemplate(newTemplateString, {
templatePlaceHolderName: 'foo' //for teplate with placeholders like ${templatePlaceHolderName}
}, domNodeToInsertIn, 'only'); //last parameter is same as dojo/dom-construct::place() >> last, first, before, after, only