如何使用表格内部淘汰foreach绑定

问题描述 投票:0回答:1

我有一个页面,显示作者列表以及我希望能够上传图像的每位作者。我在foreach中有一个表单(对于每个作者或咨询编辑),它调用自定义绑定函数“fileupload”,它是上传图像并调用API端点的处理程序。

问题出在API URL上

this.EditorImageUploadUrl(Api.baseApi + "/topics/" + this.Id + "/uploadEditorImage/" + e.AuthorRef);

它总是返回一个作者引用,这是数组中的最后一个,而不是我选择的实际作者......我是否以错误的方式进行此操作?如何返回正确的URL?有没有更好的方法来写这个?

谢谢

HTML

  <div class="consulting-editors" data-bind="foreach: ConsultingEditors">

        <i class="fa fa-times" data-bind="click: $parent.removeConsultingEditor"></i>
        <span class="editor-name" data-bind="text: AuthorName"></span>

        <form method="post" enctype="multipart/form-data" data-bind="fileupload: { url: $parent.EditorImageUploadUrl }" class="form-horizontal">
            <div class="upload-image">
                <div class="button">
                    <span class="btn btn-success fileinput-button">
                        <input type="file" id="file" class="hidden" />
                        <label for="file">Add editor photo</label>
                    </span>
                </div>
                <div class="progress" style="width: 30%; float: left; margin: 10px 0 0; display:none;">
                    <div class="bar" style="width: 0%;"></div>
                </div>
                <div class="info" style="width:30%; float:left; margin: 10px 0 0; display:none;"></div>
            </div>
        </form>

        <div class="editor-image">
            <img data-bind="attr: { src: EditorImageUrl }" />
        </div>

    </div>

获取图片上传URL和源路径

export class Topic {

    ConsultingEditors: KnockoutObservableArray<NavigatorAuthorApi> = ko.observableArray();
    EditorImageUploadUrl: KnockoutObservable<string> = ko.observable();
    EditorImageSource: KnockoutObservable<string[]> = ko.observable();

    removeConsultingEditor = (editor: NavigatorAuthorApi) => {
        this.ConsultingEditors.remove(editor);
    }


    constructor(data: NavigatorTopicApi) {
        this.Id = data.Id;
        this.ConsultingEditors(data.ConsultingEditors);

        data.ConsultingEditors.forEach((e) => {
            e.EditorImageUrl = 'data:image/jpeg;base64,' + e.EditorImage;
            this.EditorImageUploadUrl(Api.baseApi + "/topics/" + this.Id + "/uploadEditorImage/" + e.AuthorRef);
        });

        ...
    }
}


export type NavigatorAuthorApi =
    {
        SortOrder: number,
        FirmRef: number,
        FirmName: string,
        AuthorRef: number,
        AuthorName: string,
        DisplayString: string,
        EditorImage: ByteString[],
        EditorImageUrl: string
    }

Fileupload脚本

import { ConfirmDialog } from '../../Components/Typescript/confirmdialog';

declare global {
    interface JQuery {
        fileupload(option: any, url?: any, value?: any): any;
        confirmDialog: ConfirmDialog;
    }
}

export default function init(ko: KnockoutStatic) {
    ko.bindingHandlers.fileupload = {
        init: function (element, valueAccessor, allBindings) {
            var config = ko.unwrap(valueAccessor());
            var url = ko.unwrap(config.url);
            var confirmDialog =  new ConfirmDialog("#confirmDialog");


            $(element).fileupload({
                add: function (e, data) {
                    var acceptFileTypes = config.acceptFileTypes || /(\.|\/)(jpg|gif|jpeg|png)$/i; // default to just images
                    if (data.originalFiles[0]['type'].length && !acceptFileTypes.test(data.originalFiles[0]['name'])) {
                        confirmDialog.showFailure({ title: "Error", subHeader: "Files of this type cannot be uploaded"});
                    }
                    else {
                        data.submit();
                    }
                },
                url: url,
                type: 'POST',
                progressall: function (e, data) {
                    var calc = data.loaded / data.total * 100;
                    var progress = parseInt(calc.toString(), 10);
                    $(element).find('.progress .bar').css(
                        'width',
                        progress + '%'
                    );
                    var filesize, loaded;
                    if (data.total >= 1000000000) {
                        filesize = (data.total / 1000000000).toFixed(2) + ' Gbit/s';
                    }
                    else if (data.total >= 1000000) {
                        filesize = (data.total / 1000000).toFixed(2) + ' Mbit/s';
                    }
                    else if (data.total >= 1000) {
                        filesize = (data.total / 1000).toFixed(2) + ' kbit/s';
                    }
                    else {
                        filesize = data.total.toFixed(2) + ' bit/s';
                    }

                    if (data.loaded >= 1000000000) {
                        loaded = (data.loaded / 1000000000).toFixed(2) + ' Gbit/s';
                    }
                    else if (data.loaded >= 1000000) {
                        loaded = (data.loaded / 1000000).toFixed(2) + ' Mbit/s';
                    }
                    else if (data.loaded >= 1000) {
                        loaded = (data.loaded / 1000).toFixed(2) + ' kbit/s';
                    }
                    else {
                        loaded = data.loaded.toFixed(2) + ' bit/s';
                    }

                    $(element).find('.info').html(loaded + '/' + filesize);
                },
                start: function (e, data) {
                    $(element).find('.progress, .info').show();
                },
                done: function (e, data) {
                    setTimeout(function () {
                        $(element).find('.progress, .info').fadeOut(400, function () {
                            $(element).find('.progress .bar').css('width', '0%');
                        });
                    }, 500);

                    confirmDialog.showSuccess({ title: "Success", subHeader: "Image uploaded successfully" });

                },
                fail: function (e, data) {
                    setTimeout(function () {
                        $(element).find('.progress, .info').fadeOut(400, function () {
                            $(element).find('.progress .bar').css('width', '0%');
                        });
                    }, 500);

                    var xhrObject = data.xhr();
                    if (xhrObject && xhrObject.status == '412') {
                        confirmDialog.showFailure({ title: "Error", subHeader: "Failed to upload image " + xhrObject });
                    } else {
                        confirmDialog.showFailure({ title: "Error", subHeader: "Failed to upload image " + data });
                    }
                }
            });
        }
    };
} 

API端点

    [Route("topics/{topicId}/uploadEditorImage/{authorRef}")]
    [HttpPost]
    public async Task<HttpResponseMessage> UpdateEditorImage(Guid topicId, int authorRef)
    {
        HttpResponseMessage response = Request.CreateResponse(HttpStatusCode.UnsupportedMediaType);

        if (topicId != null)
        {
            if (Request.Content.IsMimeMultipartContent())
            {
                var provider = new MultipartMemoryStreamProvider();
                await Request.Content.ReadAsMultipartAsync(provider);

                var file = provider.Contents.First();
                var data = await file.ReadAsByteArrayAsync();

                await topicService.UploadEditorImage(topicId, authorRef, data);
                return Request.CreateResponse(HttpStatusCode.OK);
            }
        }
        else
        {
            response = Request.CreateResponse(HttpStatusCode.BadRequest, "The topic does not exist");
        }
        return response;

    }
c# forms typescript knockout.js foreach
1个回答
0
投票

@adiga是对的,你只是在每次迭代Topic.EditorImageUploadUrl上静态地重新分配data.ConsultingEditors.forEach,显然最后以最后一个authorRef结束,也许你可以只创建onClick而不是提前?例如

html绑定:fileupload: { url: $parent.EditorImageUploadUrl, authorRef: authorRef }

并在绑定处理程序:var authorRef = config.authorRefso,你可以在fileupload bindinghandler中构造url

**评论后更新

那你为什么不在NavigatorAuthorApi-property上的NavigatorAuthorApi.EditorImageUploadUrl类中输入url,这样你就可以为你的数据列表中的每个对象找到一个正确的url,我甚至认为这是你的意图,但你有一个this而不是e

data.ConsultingEditors.forEach((e) => {
            e.EditorImageUrl = 'data:image/jpeg;base64,' + e.EditorImage;
            e.EditorImageUploadUrl(Api.baseApi + "/topics/" + this.Id + "/uploadEditorImage/" + e.AuthorRef);
        });
© www.soinside.com 2019 - 2024. All rights reserved.