Javascript 如何在Aurelia中注入/替换部分视图和视图模型

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) {

我正在从KnockoutJS迁移到Aurelia,很难弄清楚如何从视图中交换一些HTML/JS。我有一些现有的淘汰代码,如下所示:

$.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)插槽
,但我认为这不适用于这里,尽管我可能错了。

如评论中所述,我对您的回答应该在这里起作用。给定此
运行时视图
元素:

打字稿

从“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){}
这是我的爱好