如何修复在cshtml视图中的两个地方使用时mentionsInput插件不起作用

Posted

技术标签:

【中文标题】如何修复在cshtml视图中的两个地方使用时mentionsInput插件不起作用【英文标题】:How to fix mentionsInput plugin not working when used at two places in cshtml view 【发布时间】:2020-02-08 16:00:30 【问题描述】:

我有一个评论部分,我结合使用 knockoutjs 和一个名为 jquery.mentionsInput 的插件来启用在 cmets 中提及其他人并通知他们。当评论此作品完美时,您可以看到人员列表,他们会收到通知。但我也有一个“回复”按钮,如果你点击它就会出现。注释时结构相同,文本区域相同等。但这里的提及脚本根本没有触发。

我尝试在提及脚本中创建重复的相同方法,只更改方法的名称,并将它们指向其他类,例如:原始脚本指向 '$('textarea.mention') 和回复 textarea到 '$('textarea.mention-reply') 但没有骰子..

我尝试创建两个插件脚本和 css 的副本,将每个 'mentionsInput' 和 'mention' 类替换为 'replyInput' 和 'reply' 类。没有骰子..

回复文本区域隐藏在我显示的模板中,如果您单击“回复”,我尝试将其移出模板,直接将其添加到 html 结构中。没有骰子..

问题是,如果我将原始 textarea.mention 更改为 textarea.mention-reply 并且在其他 textarea 中没有任何其他类,它就可以工作。这样就可以确认插件的副本正在运行。他们只是似乎无法在同一时间/同一视图中工作?

原始脚本:

$(function () 

    $('textarea.mention').mentionsInput(
        onDataRequest: function (mode, query, callback) 

            $.when($.getJSON("/search/PeopleMention",  searchTerm: query ))
                .done(function (dataUsers) 
                    data = $.map(dataUsers.users,
                        function (item) 
                            return 
                                'id': item.id,
                                'name': '@' + item.firstname + ' ' + item.lastname,
                                'display': item.firstname + ' ' + item.lastname,
                                'avatar': item.image,
                                'type': 'contact',
                                'link': '/Info/Profilsida/?CurrentUser=' + item.id
                            ;
                        );
                    data = _.filter(data, function (item)  return item.display.toLowerCase().indexOf(query.toLowerCase()) > -1 );
                    callback.call(this, data);
                );
        
    );


    $('.comment-button').click(function () 
        $('textarea.mention').mentionsInput('getMentions', function (data) 
            var ids = "";
            var names = "";
            $.each(data,
                function (i) 
                    names += this.name + ';';
                    ids += this.id + ';';
                );
            $('.names-container').text(names);
            $('.notification-container').text(ids);
        );
    );
);

副本看起来完全一样,但有:

$('textarea.mention-reply').mentionsReply .... 

$('.mentions-reply-button').click .... 

knockoutjs 脚本的相关部分:

function CommentsModel() 
    var that = this;

    that.replyToId = ko.observable(0);
    that.newCommentText = ko.observable();
    that.comments = ko.observableArray();

    that.updateComments = function (comments) 
        that.comments(that.sortComments(comments));
    ;

    that.addComment = function () 

        var mentionsArray = matchMentionsWithNamesInPostComment();
        var encodedCommentText = '';

        if (mentionsArray.length > 0) 
            that.newCommentText(addLinksToMentionsInComment(that.newCommentText(), mentionsArray));
            encodedCommentText = encodeURIComponent(that.newCommentText());
        

        var mentions = $('.notification-container').text();
        $.ajax(
            url: '/socialfunctions/addcomment/',
            type: 'POST',
            data:  id: $('#CurrentPageId').val(), comment: encodedCommentText == '' ? that.newCommentText() : encodedCommentText, mentions: mentions ,parentId: that.replyToId() 
        )
            .done(function (result) 
                    ........
            );
    ;

    that.post = function() 
        setTimeout(function () 
            that.addComment();
        , 500);
    ;


    that.clickedReply = function (comment) 
        if (that.replyToId() === 0 || that.replyToId() !== comment.Id) 
            that.replyToId(comment.Id);
         else 
            that.cancelReply();
        
    ;

    that.cancelReply = function () 
        that.replyToId(0);
        that.newCommentText('');
    ;

    that.deleteComment = function (comment) 
            .....
    ;

观点:

    var clientResources = ServiceLocator.Current.GetInstance<IRequiredClientResourceList>();
    clientResources.RequireStyle("\\Static\\css\\jquery.mentionsInput.css").AtHeader();
    clientResources.RequireStyle("\\Static\\css\\jquery.mentionsReply.css").AtHeader();
    clientResources.RequireScript("\\Scripts\\site\\underscore-min.js").AtFooter();
    clientResources.RequireScript("\\Scripts\\jQuery\\jquery.elastic.source.js").AtFooter();
    clientResources.RequireScript("\\Scripts\\jQuery\\jquery.mentionsInput.js").AtFooter();
    clientResources.RequireScript("\\Scripts\\jQuery\\jquery.mentionsInputInit.js").AtFooter();
    clientResources.RequireScript("\\Scripts\\jQuery\\jquery.mentionsReply.js").AtFooter();
    clientResources.RequireScript("\\Scripts\\jQuery\\jquery.mentionsReplyInit.js").AtFooter();

    <div id="comments">
        <div class="clearfix">
            <div class="form-group">

                <h4>Kommentera</h4>
                <p class="infotext">Please write a comment</p>
                <textarea data-bind="visible: replyToId() == 0, textInput:newCommentText" class="mention form-control fullwidth" maxlength="4000"></textarea>
            </div>
            <div class="button-div">
                <span style="display: none;" class="notification-container"></span>
                <span style="display: none;" class="names-container"></span>
                <a href="/" data-bind="visible: replyToId() == 0, click:post" class="comment-button button">Send</a>
            </div>
        </div>
        <script type="text/html" id="reply-template">
            <div class="clearfix" data-bind="visible:$root.replyToId() == Id">
                <div class="form-group">
                    <h5>Svara <span data-bind="text: UserFullName"></span></h5>
                    <textarea data-bind="textInput:$root.newCommentText" class="mention-reply form-control fullwidth" maxlength="4000"></textarea>
                </div>
                <div class="button-div">
                    <a href="/" data-bind="click:$root.post" class="mentions-reply-button button">Send</a>
                    <a href="/" data-bind="click:$root.cancelReply" class="button">Cancel</a>
                </div>
            </div>
        </script>
        <div data-bind="visible:comments() == undefined || comments().length == 0">
            Right now there are no comments. Be the first to comment!
        </div>

        <div data-bind="foreach:comments">
            <div class="comment clearfix" data-bind="css:  reply: ParentId > 0 ">
                <div class="info">
                    <a data-bind="text:UserFullName, attr:href:UserProfilePageLink"></a>
                    <span class="date" data-bind="text: moment(CreateDate).format('YYYY-MM-DD')"></span>
                    <a class="reply-button pull-right" data-bind="visible: ParentId == 0, click: $parent.clickedReply">Reply</a>
                </div>
                <div data-bind="html:Comment, attr:  'id': Id "></div>
                @if (EPiServer.Security.PrincipalInfo.HasAdminAccess)
                
                    <a href="#" class="button remove pull-right" data-bind="click:$parent.deleteComment">Remove</a>
                
                <div class="reply" data-bind="template:  name: 'reply-template', data: $data "></div>
            </div>
        </div>
    </div>

我希望提及插件在两个文本区域中都可以使用,但它仅在评论文本区域中有效,而不是在回复文本区域中。它永远不会触发。没有错误什么都没有。同样,这两个版本的脚本都在第一个文本区域中工作,它们都不能在回复文本区域中工作。

【问题讨论】:

【参考方案1】:

我在这里找到了答案:

JQuery: Selecting dynamically created elements and pushing to Firebase

为 cmets 的循环创建了一个 div“.reply-container”(也呈现回复模板)并将脚本包装在

$('#reply-container').on('click', '.reply-button', function () ...

【讨论】:

以上是关于如何修复在cshtml视图中的两个地方使用时mentionsInput插件不起作用的主要内容,如果未能解决你的问题,请参考以下文章

如何修复 PWA 审核中的“当 JavaScript 不可用时不提供后备内容”?

识别最大值行然后在其他地方使用时出现索引越界错误

使用 razor cshtml 渲染 XML 时,如何在 Visual Studio 中修复或删除验证

视图(.cshtml)文件中的编译错误

模型不会从剃刀页面中的 _Layout.cshtml 页面中的 _Footer.cshtml 部分视图绑定

如何修复汉堡菜单动画?