Javascript 如何在Aurelia中注入/替换部分视图和视图模型
我正在从KnockoutJS迁移到Aurelia,很难弄清楚如何从视图中交换一些HTML/JS。我有一些现有的淘汰代码,如下所示:Javascript 如何在Aurelia中注入/替换部分视图和视图模型,javascript,asp.net-core,aurelia,Javascript,Asp.net Core,Aurelia,我正在从KnockoutJS迁移到Aurelia,很难弄清楚如何从视图中交换一些HTML/JS。我有一些现有的淘汰代码,如下所示: $.ajax({ url: "/admin/configuration/settings/get-editor-ui/" + replaceAll(self.type(), ".", "-"), type: "GET", dataType: "json", async: false }) .done(function (json) {
$.ajax({
url: "/admin/configuration/settings/get-editor-ui/" + replaceAll(self.type(), ".", "-"),
type: "GET",
dataType: "json",
async: false
})
.done(function (json) {
// Clean up from previously injected html/scripts
if (typeof cleanUp == 'function') {
cleanUp(self);
}
// Remove Old Scripts
var oldScripts = $('script[data-settings-script="true"]');
if (oldScripts.length > 0) {
$.each(oldScripts, function () {
$(this).remove();
});
}
var elementToBind = $("#form-section")[0];
ko.cleanNode(elementToBind);
var result = $(json.content);
// Add new HTML
var content = $(result.filter('#settings-content')[0]);
var details = $('<div>').append(content.clone()).html();
$("#settings-details").html(details);
// Add new Scripts
var scripts = result.filter('script');
$.each(scripts, function () {
var script = $(this);
script.attr("data-settings-script", "true");//for some reason, .data("block-script", "true") doesn't work here
script.appendTo('body');
});
// Update Bindings
// Ensure the function exists before calling it...
if (typeof updateModel == 'function') {
var data = ko.toJS(ko.mapping.fromJSON(self.value()));
updateModel(self, data);
ko.applyBindings(self, elementToBind);
}
//self.validator.resetForm();
switchSection($("#form-section"));
})
.fail(function (jqXHR, textStatus, errorThrown) {
$.notify(self.translations.getRecordError, "error");
console.log(textStatus + ': ' + errorThrown);
});
@using Framework.Web
@using Framework.Web.Configuration
@inject Microsoft.Extensions.Localization.IStringLocalizer T
@model DateTimeSettings
<div id="settings-content">
<div class="form-group">
@Html.LabelFor(m => m.DefaultTimeZoneId)
@Html.TextBoxFor(m => m.DefaultTimeZoneId, new { @class = "form-control", data_bind = "value: defaultTimeZoneId" })
@Html.ValidationMessageFor(m => m.DefaultTimeZoneId)
</div>
<div class="checkbox">
<label>
@Html.CheckBoxFor(m => m.AllowUsersToSetTimeZone, new { data_bind = "checked: allowUsersToSetTimeZone" }) @T[FrameworkWebLocalizableStrings.Settings.DateTime.AllowUsersToSetTimeZone]
</label>
</div>
</div>
<script type="text/javascript">
function updateModel(viewModel, data) {
viewModel.defaultTimeZoneId = ko.observable("");
viewModel.allowUsersToSetTimeZone = ko.observable(false);
if (data) {
if (data.DefaultTimeZoneId) {
viewModel.defaultTimeZoneId(data.DefaultTimeZoneId);
}
if (data.AllowUsersToSetTimeZone) {
viewModel.allowUsersToSetTimeZone(data.AllowUsersToSetTimeZone);
}
}
};
function cleanUp(viewModel) {
delete viewModel.defaultTimeZoneId;
delete viewModel.allowUsersToSetTimeZone;
}
function onBeforeSave(viewModel) {
var data = {
DefaultTimeZoneId: viewModel.defaultTimeZoneId(),
AllowUsersToSetTimeZone: viewModel.allowUsersToSetTimeZone()
};
viewModel.value(ko.mapping.toJSON(data));
};
</script>
我使用EditorTemplatePath
属性呈现该视图并在AJAX请求中返回它。设置视图示例如下所示:
$.ajax({
url: "/admin/configuration/settings/get-editor-ui/" + replaceAll(self.type(), ".", "-"),
type: "GET",
dataType: "json",
async: false
})
.done(function (json) {
// Clean up from previously injected html/scripts
if (typeof cleanUp == 'function') {
cleanUp(self);
}
// Remove Old Scripts
var oldScripts = $('script[data-settings-script="true"]');
if (oldScripts.length > 0) {
$.each(oldScripts, function () {
$(this).remove();
});
}
var elementToBind = $("#form-section")[0];
ko.cleanNode(elementToBind);
var result = $(json.content);
// Add new HTML
var content = $(result.filter('#settings-content')[0]);
var details = $('<div>').append(content.clone()).html();
$("#settings-details").html(details);
// Add new Scripts
var scripts = result.filter('script');
$.each(scripts, function () {
var script = $(this);
script.attr("data-settings-script", "true");//for some reason, .data("block-script", "true") doesn't work here
script.appendTo('body');
});
// Update Bindings
// Ensure the function exists before calling it...
if (typeof updateModel == 'function') {
var data = ko.toJS(ko.mapping.fromJSON(self.value()));
updateModel(self, data);
ko.applyBindings(self, elementToBind);
}
//self.validator.resetForm();
switchSection($("#form-section"));
})
.fail(function (jqXHR, textStatus, errorThrown) {
$.notify(self.translations.getRecordError, "error");
console.log(textStatus + ': ' + errorThrown);
});
@using Framework.Web
@using Framework.Web.Configuration
@inject Microsoft.Extensions.Localization.IStringLocalizer T
@model DateTimeSettings
<div id="settings-content">
<div class="form-group">
@Html.LabelFor(m => m.DefaultTimeZoneId)
@Html.TextBoxFor(m => m.DefaultTimeZoneId, new { @class = "form-control", data_bind = "value: defaultTimeZoneId" })
@Html.ValidationMessageFor(m => m.DefaultTimeZoneId)
</div>
<div class="checkbox">
<label>
@Html.CheckBoxFor(m => m.AllowUsersToSetTimeZone, new { data_bind = "checked: allowUsersToSetTimeZone" }) @T[FrameworkWebLocalizableStrings.Settings.DateTime.AllowUsersToSetTimeZone]
</label>
</div>
</div>
<script type="text/javascript">
function updateModel(viewModel, data) {
viewModel.defaultTimeZoneId = ko.observable("");
viewModel.allowUsersToSetTimeZone = ko.observable(false);
if (data) {
if (data.DefaultTimeZoneId) {
viewModel.defaultTimeZoneId(data.DefaultTimeZoneId);
}
if (data.AllowUsersToSetTimeZone) {
viewModel.allowUsersToSetTimeZone(data.AllowUsersToSetTimeZone);
}
}
};
function cleanUp(viewModel) {
delete viewModel.defaultTimeZoneId;
delete viewModel.allowUsersToSetTimeZone;
}
function onBeforeSave(viewModel) {
var data = {
DefaultTimeZoneId: viewModel.defaultTimeZoneId(),
AllowUsersToSetTimeZone: viewModel.allowUsersToSetTimeZone()
};
viewModel.value(ko.mapping.toJSON(data));
};
</script>
使用Framework.Web
@使用Framework.Web.Configuration
@注入Microsoft.Extensions.Localization.IStringLocalizer T
@模型日期时间设置
@LabelFor(m=>m.DefaultTimeZoneId)
@Html.TextBoxFor(m=>m.DefaultTimeZoneId,新的{@class=“form control”,data_bind=“value:DefaultTimeZoneId”})
@Html.ValidationMessageFor(m=>m.DefaultTimeZoneId)
@Html.CheckBoxFor(m=>m.allowUserSetTimeZone,new{data_bind=“checked:allowUserSetTimeZone”})@T[FrameworkWebLocalizableStrings.Settings.DateTime.AllowUserSetTimeZone]
函数updateModel(视图模型、数据){
viewModel.defaultTimeZoneId=ko.observable(“”);
viewModel.allowUsersToSetTimeZone=ko.可观察(假);
如果(数据){
if(data.DefaultTimeZoneId){
viewModel.defaultTimeZoneId(data.defaultTimeZoneId);
}
if(data.AllowUsersToSetTimeZone){
viewModel.allowUsersToSetTimeZone(data.allowUsersToSetTimeZone);
}
}
};
函数清理(viewModel){
删除viewModel.defaultTimeZoneId;
删除viewModel.allowUsersToSetTimeZone;
}
函数onBeforeSave(视图模型){
风险值数据={
DefaultTimeZoneId:viewModel.DefaultTimeZoneId(),
AllowUsersToSetTimeZone:viewModel.AllowUsersToSetTimeZone()
};
value(ko.mapping.toJSON(数据));
};
现在,如果您回到AJAX请求,看看我在那里做什么,它应该更有意义。我在
中注入此HTML,如下所示:
$.ajax({
url: "/admin/configuration/settings/get-editor-ui/" + replaceAll(self.type(), ".", "-"),
type: "GET",
dataType: "json",
async: false
})
.done(function (json) {
// Clean up from previously injected html/scripts
if (typeof cleanUp == 'function') {
cleanUp(self);
}
// Remove Old Scripts
var oldScripts = $('script[data-settings-script="true"]');
if (oldScripts.length > 0) {
$.each(oldScripts, function () {
$(this).remove();
});
}
var elementToBind = $("#form-section")[0];
ko.cleanNode(elementToBind);
var result = $(json.content);
// Add new HTML
var content = $(result.filter('#settings-content')[0]);
var details = $('<div>').append(content.clone()).html();
$("#settings-details").html(details);
// Add new Scripts
var scripts = result.filter('script');
$.each(scripts, function () {
var script = $(this);
script.attr("data-settings-script", "true");//for some reason, .data("block-script", "true") doesn't work here
script.appendTo('body');
});
// Update Bindings
// Ensure the function exists before calling it...
if (typeof updateModel == 'function') {
var data = ko.toJS(ko.mapping.fromJSON(self.value()));
updateModel(self, data);
ko.applyBindings(self, elementToBind);
}
//self.validator.resetForm();
switchSection($("#form-section"));
})
.fail(function (jqXHR, textStatus, errorThrown) {
$.notify(self.translations.getRecordError, "error");
console.log(textStatus + ': ' + errorThrown);
});
@using Framework.Web
@using Framework.Web.Configuration
@inject Microsoft.Extensions.Localization.IStringLocalizer T
@model DateTimeSettings
<div id="settings-content">
<div class="form-group">
@Html.LabelFor(m => m.DefaultTimeZoneId)
@Html.TextBoxFor(m => m.DefaultTimeZoneId, new { @class = "form-control", data_bind = "value: defaultTimeZoneId" })
@Html.ValidationMessageFor(m => m.DefaultTimeZoneId)
</div>
<div class="checkbox">
<label>
@Html.CheckBoxFor(m => m.AllowUsersToSetTimeZone, new { data_bind = "checked: allowUsersToSetTimeZone" }) @T[FrameworkWebLocalizableStrings.Settings.DateTime.AllowUsersToSetTimeZone]
</label>
</div>
</div>
<script type="text/javascript">
function updateModel(viewModel, data) {
viewModel.defaultTimeZoneId = ko.observable("");
viewModel.allowUsersToSetTimeZone = ko.observable(false);
if (data) {
if (data.DefaultTimeZoneId) {
viewModel.defaultTimeZoneId(data.DefaultTimeZoneId);
}
if (data.AllowUsersToSetTimeZone) {
viewModel.allowUsersToSetTimeZone(data.AllowUsersToSetTimeZone);
}
}
};
function cleanUp(viewModel) {
delete viewModel.defaultTimeZoneId;
delete viewModel.allowUsersToSetTimeZone;
}
function onBeforeSave(viewModel) {
var data = {
DefaultTimeZoneId: viewModel.defaultTimeZoneId(),
AllowUsersToSetTimeZone: viewModel.allowUsersToSetTimeZone()
};
viewModel.value(ko.mapping.toJSON(data));
};
</script>
我正在想办法在奥雷利亚如何做到这一点。我发现我可以使用Aurelia的
templatingEngine.enhance({element:elementToBind,bindingContext:this})代码>而不是敲除的ko.applyBindings(self,elementToBind)因此我认为应该将新属性绑定到视图模型。但是,我不知道如何处理设置编辑器模板中的脚本。我想我可以尝试保持我已经拥有的相同逻辑(使用jQuery添加/删除脚本等等)。。。但我希望有一个更干净/更优雅的解决方案来解决这个问题。我查看了插槽
,但我认为这不适用于这里,尽管我可能错了。如评论中所述,我对您的回答应该在这里起作用。给定此运行时视图
元素:
打字稿
从“aurelia binding”导入{bindingMode,createOverrideContext};
从“aurelia依赖项注入”导入{Container};
从“aurelia任务队列”导入{TaskQueue};
从“aurelia模板”导入{bindable、customElement、inlineView、ViewCompiler、ViewResources、ViewSlot};
@customElement(“运行时视图”)
@inlineView(“”)
导出类运行时视图{
@可绑定({defaultBindingMode:bindingMode.toView})
公共html:string;
@可绑定({defaultBindingMode:bindingMode.toView})
公共背景:任何;
公共el:HTMLElement;
公共窗口:视图窗口;
公共绑定上下文:任何;
公共文本:任何;
公共isAttached:boolean;
公共isRendered:布尔值;
公共需求需求需求:布尔型;
专用tq:任务队列;
私人集装箱:集装箱;
私有视图编译器:视图编译器;
构造函数(el:Element,tq:TaskQueue,container:container,viewCompiler:viewCompiler){
this.el=el作为HTMLElement;
this.tq=tq;
this.container=容器;
this.viewCompiler=viewCompiler;
this.slot=this.bindingContext=this.overrideContext=null;
this.isAttached=this.isRendered=this.needsRender=false;
}
公共绑定(bindingContext:any,overrideContext:any):void{
this.bindingContext=this.context | | bindingContext.context | bindingContext;
this.overrideContext=createOverrideContext(this.bindingContext,overrideContext);
this.htmlChanged();
}
public unbind():void{
this.bindingContext=null;
this.overrideContext=null;
}
公共附件():无效{
this.slot=新的ViewSlot(this.el.firstElementChild | | this.el,true);
this.isAttached=true;
this.tq.queueMicroTask(()=>{
this.tryRender();
});
}
公共分离():无效{
this.isAttached=false;
如果(本文件已招标){
这个.cleanUp();
}
this.slot=null;
}
私有htmlChanged():void{
this.tq.queueMicroTask(()=>{
this.tryRender();
});
}
私有上下文已更改():void{
this.tq.queueMicroTask(()=>{
this.tryRender();
});
}
私有tryRender():void{
如果(本文件已附加){
如果(本文件已招标){
这个.cleanUp();
}
试一试{
this.tq.queueMicroTask(()=>{
这个。render();
});
}捕获(e){
this.tq.queueMicroTask(()=>{
this.render(`${e.message}`);
});
}
}
}
私有清理():void{
试一试{
this.slot.detached();
}捕获(e){}
试一试{
this.slot.unbind();
}捕获(e){}
试一试{
this.slot.removeAll();
}捕获(e){}
这是我的爱好