(底部说明)
有帮助:在开头和结尾都有(*)的代码行是我上线的行。
嘿伙计们,我对自定义dojo小部件存在严重问题。
我有以下代码(services.aspx):
<asp:Content ID="Content2" ContentPlaceHolderID="formdojoRequirementsPlaceHolder"
runat="Server">
<script type="text/javascript">
dojo.require("js.Forms.ServiceDetails");
dojo.require("js.Forms.PendingServices");
dojo.require("js.Forms.CertificatesList");
dojo.addOnLoad(function() {
//LOCALIZATION
var glb_connections = [];
var ServiceDetailsTab = dijit.byId('ServiceDetails');
var PendingTaskTab = dijit.byId('PendingTask');
var PendingServicesTab = dijit.byId('PendingServices');
var CertificatesListTab = dijit.byId('CertificatesList');
var MessagesTab = dijit.byId('Messages');
if (ServiceDetailsTab) { ServiceDetailsTab.attr('title', glb_nlsStrings.ServiceTab) };
if (PendingTaskTab) { PendingTaskTab.attr('title', glb_nlsStrings.PendingTaskTab) };
if (PendingServicesTab) { PendingServicesTab.attr('title', glb_nlsStrings.PendingServicesTab) };
if (CertificatesListTab) { CertificatesListTab.attr('title', glb_nlsStrings.CertificatesTab) };
if (MessagesTab) { MessagesTab.attr('title', glb_nlsStrings.MessagesTab) };
ServiceDetailsTab = null;
PendingTaskTab = null;
PendingServicesTab = null;
CertificatesListTab = null;
MessagesTab = null;
//
var queryObj = Utils.General.GetQueryStringObject(window.location.href);
var organizationId = queryObj[Utils.General.Constants.queryParameters.ORGANIZATIONID];
var serviceTypeCode = queryObj[Utils.General.Constants.queryParameters.SERVICETYPECODE];
var tab = queryObj['glb_currentTab'];
if (dojo.byId("ServiceDetailsWdj") != undefined) {
*djtServiceDetails.serviceTypeCode = serviceTypeCode;*
glb_connections.push(dojo.connect(djtPendingServices, "onServiceInstanceDeleted", function() {
*djtServiceDetails.onBack();*
}));
*glb_connections.push(dojo.connect(djtServiceDetails, "onServiceCompleted", function() {
djtPendingServices._FindIncompleteServices(serviceTypeCode, glb_site_userID, organizationId);
}));*
}
else {
removeTab("ServiceDetails")
}
if (dojo.byId("PendingTaskWdj") != undefined) {
glb_subscriptions.push(dojo.subscribe("_serviceInstanceDeleted", function(child) {
*djtPendingServices._FindIncompleteServices(serviceTypeCode, glb_site_userID, organizationId);*
}));
glb_connections.push(dojo.connect(djtPendingServices, "onServiceInstanceCompleted", function() {
djtPendingServices._FindIncompleteServices(serviceTypeCode, glb_site_userID, organizationId);
if (dojo.byId("ServiceDetailsWdj") != undefined) { *djtServiceDetails.postCreate();* }
}));
djtPendingServices._FindIncompleteServices(serviceTypeCode, glb_site_userID, organizationId);
}
else {
removeTab("PendingTask")
}
removeTab("dataToBeSubmittedTab");
if (tab != undefined) {
glb_currentTab = tab;
var tabContainerWidget = dijit.byId('tabContainer');
tabContainerWidget.selectChild(glb_currentTab);
} else {
glb_currentTab = 'ServiceDetails';
}
glb_subscriptions.push(dojo.subscribe("tabContainer-selectChild", function(child) {
glb_currentTab = child.id;
}));
});
function removeTab(tabId) {
var tabContainerDijit = dijit.byId("tabContainer");
if (tabContainerDijit) {
var dataToBeSubmittedTabDijit = dijit.byId(tabId);
if (dataToBeSubmittedTabDijit) {
tabContainerDijit.removeChild(dataToBeSubmittedTabDijit);
}
}
}
dojo.addOnUnload(function() {
if (typeof glb_connections != "undefined")
dojo.forEach(glb_connections, dojo.disconnect);
if (typeof glb_subscriptions != "undefined")
dojo.forEach(glb_subscriptions, dojo.unsubscribe);
});
</script>
</asp:Content>
<asp:Content ID="Content3" ContentPlaceHolderID="formMainContentPlaceHolder" runat="Server">
<div id="ServiceDetails" dojotype="dijit.layout.ContentPane" title="Services" style="height: 95%">
<div id="divServiceDetails" runat="server">
<div dojotype="js.Forms.ServiceDetails" jsid="djtServiceDetails" id="ServiceDetailsWdj">
</div>
</div>
</div>
<div id="PendingTask" dojotype="dijit.layout.ContentPane" title="Pending Tasks" style="height: 95%">
<div id="divPendingTask" runat="server">
<div dojotype="js.Forms.PendingServices" jsid="djtPendingServices" id="PendingTaskWdj">
</div>
</div>
</div>
<div id="CertificatesList" dojotype="dijit.layout.ContentPane" title="Certificates"
style="height: 95%">
<div id="divCertificatesList" runat="server">
<div dojotype="js.Forms.CertificatesList">
</div>
</div>
</div>
</asp:Content>
The 3 files : 1.dojo.require("js.Forms.ServiceDetails");
2.dojo.require("js.Forms.PendingServices");
3.dojo.require("js.Forms.CertificatesList");
是小部件。
小部件是基于MVC构建的。
这里重要的是视图部分出现问题所以View的代码如下:
dojo.provide("js.Forms.Views.ServiceDetailsView");
dojo.require("js.Forms.Controllers.ServiceDetailsController");
dojo.require("js.FormSteps.FormsList");
dojo.require("js.FormSteps.IncompleteServices");
dojo.require("BL.DataContracts.Entities.FormDefinition");
dojo.require("BL.DataContracts.Entities.ServiceFormInstance");
dojo.require("dijit._Widget");
dojo.require("dojox.dtl._DomTemplated");
dojo.require("dijit.form.Button");
dojo.require("dijit.TooltipDialog");
dojo.require("dijit.form.DropDownButton");
dojo.require("dijit.form.DateTextBox");
dojo.declare("js.Forms.Views.ServiceDetailsView", [dijit._Widget, dojox.dtl._DomTemplated], {
connections: null,
controller: null,
widgetsInTemplate: true,
templatePath: dojo.moduleUrl("js.Forms", "Templates/ServicesList.html"),
servicesList: null,
serviceTypeCode: null,
servicesDefinitions: null,
inCompleteServices: null,
isDissolved: null,
constructor: function() {
this.controller = new js.Forms.Controllers.ServiceDetailsController(this);
this.nlsStrings = dojo.i18n.getLocalization("Resources", "Resources");
var queryObj = Utils.General.GetQueryStringObject(window.location.href);
this.isDissolved = queryObj[Utils.General.Constants.queryParameters.ISDISSOLVED];
},
**postCreate: function(args, frag) {
this.inherited("postCreate", arguments);
this.ConnectEvents();
dojo.style(this.divBackButton, "display", "none");
if ((this.isDissolved == 'false') || (this.isDissolved == undefined)) {
this.FindServicesDefinitions();
this.SetButtonLabels();
}
},**
SetButtonLabels: function() {
this.btnBackService.attr('label', this.nlsStrings.btnBack);
},
ConnectEvents: function() {
this.connect(this.djtIncompleteServices, 'onCreateNewService', function() {
this.showFormDefinitions();
});
this.connect(this.djtIncompleteServices, 'onIncompleteServiceLoad', function(serviceinstanceid, isReturned) {
this.djtFormsList.isReturnedService = isReturned;
this.onFilterDefinitions(serviceinstanceid);
});
this.connect(this.djtIncompleteServices, 'onIncompleteServiceDeleted', function(serviceinstanceid) {
this.onDeleteServiceInstance(serviceinstanceid);
});
this.connect(this.djtFormsList, 'onServiceCompleted', function() {
this._ServiceCompleted();
});
},
DeleteIncompleteServiceFromModel: function(serviceinstanceid) {
this.controller.model.incompleteServicesList = dojo.filter(this.controller.model.incompleteServicesList, function(serviceinstance) { return serviceinstance.serviceinstanceid != serviceinstanceid; });
this.showIncompleteServices(this.controller.model.incompleteServicesList);
dojo.publish("_serviceInstanceDeleted");
},
onDeleteServiceInstance: function(serviceinstanceid) {
this.controller.DeleteServiceInstance(serviceinstanceid);
},
FindServicesDefinitions: function() {
this.controller.FindServices();
},
BindServicesList: function(servicesList) {
this.servicesList = servicesList;
this.buildRendering();
this.ShowServicesList(this.serviceTypeCode);
},
ShowServicesList: function(serviceTypeCode) {
//debugger;
dojo.style(this.divServices, "display", "block");
if (serviceTypeCode == Utils.General.Constants.serviceTypeCode.REGISTRATIONOFORGANIZATION) {
if (glb_currentRegistrationService) {
dojo.style(this.divServices, "display", "none");
this.controller.FindIncompleteRegistrationServices();
}
}
this.servicesListHeading.innerHTML = (serviceTypeCode == Utils.General.Constants.serviceTypeCode.CHANGEOFORGANIZATION) ?
this.nlsStrings.colOrganizationChangeServices : this.nlsStrings.colOrganizationChangeServices;
},
BindIncompleteRegistrationServices: function() {
//debugger;
dojo.style(this.divServices, "display", "block");
var incompleteRegistrationServices = this.controller.GetIncompleteRegistrationServices();
var hasIncompleteRegistrationServices = (incompleteRegistrationServices != null && incompleteRegistrationServices.length > 0);
dojo.query("a[servicecode]").forEach(function(node) {
//debugger;
if (hasIncompleteRegistrationServices) {
var idx = -1;
var nodeServiceCode = dojo.attr(node, "servicecode");
var incompleteRegServices = dojo.filter(incompleteRegistrationServices, function(item) {
return item.serviceCode == nodeServiceCode;
});
if (incompleteRegServices.length == 0) {
dojo.attr(node, "disabled", "disabled");
}
else {
for (var i = 0; i < incompleteRegistrationServices.length; i++) {
if (incompleteRegistrationServices[i].serviceCode == nodeServiceCode)
idx = i;
}
if (idx >= 0) {
if (incompleteRegistrationServices[idx].shouldEnable == false)
dojo.attr(node, "disabled", "disabled");
else
node.removeAttribute("disabled");
}
}
}
else {
//There are no incomplete regisistrations for the organization name.Disable any subservices.
if (dojo.attr(node, "servicecode") != glb_currentRegistrationService) {
dojo.attr(node, "disabled", "disabled");
}
}
});
},
onselectService: function(event) {
var domNode = event.srcElement;
if (!dojo.hasAttr(domNode, 'disabled')) {
var serviceCode = dojo.attr(domNode, "serviceCode");
this.servicesDefinitions = dojo.filter(this.servicesList.OrganizationServices, function(serviceDefinition) { return serviceDefinition.ServiceDefinitionID == serviceCode; });
if (Utils.General.GetQueryStringObject(window.location.href).organizationid == undefined) {
this.inCompleteServices = this.controller.FindIncompleteServices(serviceCode, 0);
}
else {
this.inCompleteServices = this.controller.FindIncompleteServices(serviceCode, Utils.General.GetQueryStringObject(window.location.href).organizationid);
}
}
},
onFilterDefinitions: function(serviceinstanceid) {
glb_serviceInstanceID = serviceinstanceid;
var filteredDefitions = this.controller.FilterFormsDefinitions(serviceinstanceid);
},
DeleteServiceDefinitionFromClient: function(serviceinstanceid) {
},
showFilteredFormDefinitions: function() {
//debugger;
var iscomplete = true;
var modl = this.controller.model.incompleteServiceFormsList;
var servDefinitions = dojo.clone(this.servicesDefinitions[0]);
var formsDef = servDefinitions.FormsDefinitions;
var formCode = null;
if (servDefinitions.IsVariableFee) {
var registrationForm = dojo.filter(modl, function(item) {
return item.formnumber == 'XI00Z';
});
if (registrationForm.length > 0) {
servDefinitions.Fee = registrationForm[0].CalculatedVariableFee;
}
}
for (var i = 0; i < formsDef.length; i++) {
formCode = formsDef[i].FormDefinitionID;
for (var j = 0; j < modl.length; j++) {
if (modl[j].formnumber == formCode) {
//Attach some dynamic properties to the form definitions
formsDef[i].pendingtaskid = modl[j].pendingtaskid;
formsDef[i].iscomplete = modl[j].iscomplete;
formsDef[i].drcorstatus = modl[j].drcorstatus;
if ((!modl[j].isDocument) && (modl[j].Attachments.length > 0)) {
formsDef[i].DocumentGuid = modl[j].Attachments[0].DocumentID;
}
if (modl[j].iscomplete == 0) {
iscomplete = false;
}
}
}
}
this.djtFormsList.IsCompleted(iscomplete);
this.djtFormsList.SetServiceFormsDefinitions(servDefinitions);
for (var i = 0; i < modl.length; i++) {
if (modl[i].isDocument) {
//Set the attachments for each document in the incomplete service form list
this.djtFormsList.SetDocumentAttachments(modl[i].formnumber, modl[i].Attachments);
}
}
dojo.style(this.divBackButton, "display", "block");
dojo.style(this.divServices, "display", "none");
dojo.style(this.divServiceFormsDefinitions, "display", "block");
dojo.style(this.divIncompleteServices, "display", "none");
},
showIncompleteServices: function(inCompleteServices) {
this.djtIncompleteServices.SetIncompleteServicesList(inCompleteServices);
dojo.style(this.divBackButton, "display", "block");
dojo.style(this.divServices, "display", "none");
dojo.style(this.divIncompleteServices, "display", "block");
},
showFormDefinitions: function() {
this.djtFormsList.IsCompleted(false);
glb_serviceInstanceID = 0;
this.djtFormsList.SetServiceFormsDefinitions(this.servicesDefinitions[0]);
this.djtFormsList.ClearDocumentAttachments();
dojo.style(this.divBackButton, "display", "block");
dojo.style(this.divServices, "display", "none");
dojo.style(this.divServiceFormsDefinitions, "display", "block");
dojo.style(this.divIncompleteServices, "display", "none");
},
onBack: function() {
dojo.style(this.divBackButton, "display", "none");
dojo.style(this.divServices, "display", "block");
dojo.style(this.divServiceFormsDefinitions, "display", "none");
dojo.style(this.divIncompleteServices, "display", "none");
this.buildRendering();
this.ShowServicesList(this.serviceTypeCode);
},
_ServiceCompleted: function() {
glb_serviceInstanceID = 0;
dojo.style(this.divBackButton, "display", "none");
dojo.style(this.divServices, "display", "block");
dojo.style(this.divServiceFormsDefinitions, "display", "none");
dojo.style(this.divIncompleteServices, "display", "none");
this.buildRendering();
this.ShowServicesList(this.serviceTypeCode);
this.onServiceCompleted();
},
onServiceCompleted: function() {
}
});
好的,现在让我解释一下这个问题。
当我在Internet Explorer 8或7下运行此应用程序时,一切都运行良好。 但是当我尝试使用IE9,Firefox或Chrome打开它时,我收到一条错误,指出“未定义djtServiceDetails”。
正如我从调试中所理解的那样,这是因为在执行文件时,不会执行View的 postCreate 部分(永远找不到postCreate中的调试器)
我有一个类似的页面使用与上述相同的结构,适用于所有浏览器,我们无法找到任何差异。
我希望你能告诉我一些有助于我解决这个问题的事情。
如果您需要更多信息,请告诉我们。
提前谢谢
梭伦
答案 0 :(得分:0)
我有一个可能会或可能不会起作用的建议。我尝试使用简化代码重现您的问题而不能。作为一项规则,我不在我的自定义小部件中提供构造函数。构造函数中的代码可以放在postMixInProperties
。
尝试将构造函数更改为以下内容:
postMixInProperties: function() {
this.inherited(arguments);
this.controller = new js.Forms.Controllers.ServiceDetailsController(this);
this.nlsStrings = dojo.i18n.getLocalization("Resources", "Resources");
var queryObj = Utils.General.GetQueryStringObject(window.location.href);
this.isDissolved = queryObj
[Utils.General.Constants.queryParameters.ISDISSOLVED];
},
我想知道dojo.i18n调用是否会产生xhr请求,会导致您看到的行为。
答案 1 :(得分:0)
我认为解决你的标记是一个问题。这基本上是最大的警告,使用dojo,因为DOCTYPE和渲染引擎是在平台独立JS中“防范”最难的部分。我还没用过&lt; 1.7现在有一段时间,但我相当肯定正确的标记会更接近于此,使用自定义属性上的camelCase语法:
<div id="ServiceDetails" dojoType="dijit.layout.ContentPane" title="Services" style="height: 95%">
<div id="divServiceDetails" runat="server">
<div dojoType="js.Forms.ServiceDetails" jsId="djtServiceDetails" id="ServiceDetailsWdj">
</div>
</div>
</div>
<div id="PendingTask" dojoType="dijit.layout.ContentPane" title="Pending Tasks" style="height: 95%">
<div id="divPendingTask" runat="server">
<div dojoType="js.Forms.PendingServices" jsId="djtPendingServices" id="PendingTaskWdj">
</div>
</div>
</div>
<div id="CertificatesList" dojoType="dijit.layout.ContentPane" title="Certificates"
style="height: 95%">
<div id="divCertificatesList" runat="server">
<div dojoType="js.Forms.CertificatesList">
</div>
</div>
</div>
无论是通过验证器=)
,它都会显得凌乱再次,1.6我不确定,但我认为你可以替换为html5 compat属性命名模式,以便dojoType
成为data-dojo-type
而jsId
将成为data-dojo-jsId
(应该参考api中的这些。关于jsId - 你最好通过dijit注册表引用小部件 - 全球范围的曝光在未来版本中即将推出。因此,不要通过/*window.*/ djtServiceDetails
获取所述对象,而是调用dijit.byId('djtServiceDetails')
尝试一下,然后说 - 我个人也会把'title','id','valueAttr'等东西编译成dojoProps属性,这样:
<div dojoType="dijit.layout.ContentPane" jsId="registryKeyId" title="Dia Title" href="index101.html"></div>
变为
<div dojoType="dijit.layout.ContentPane" dojoProps="id:'registryKeyId', title:'Dia Title', href:'index101.html'"></div>