如何正确引用传递到淘汰中的当前元素的属性.JS

How do I correctly reference an attribute of the current element passed into knockout.JS?

本文关键字:元素 JS 属性 淘汰 引用 何正确      更新时间:2023-09-26

我是Knockout/jQuery游戏的新手,所以我确信这是一个语法错误。

目标/背景

  • 我有一个反馈表格,其中包括一个反馈类型列表。我想使用的反馈类型的实际文本存储在LI标记的"Title"属性中
  • 我想从一组表示反馈类型的li标签中的每一个标签中传递一个onclick
  • 我希望淘汰赛能收到这个带有调用元素的onclick事件
  • 我希望ViewModel函数根据li的title属性的内容更新ViewModel的反馈类型
  • 然后,我想从所有列表中删除一个类,并将其应用于选定的元素。
    • 我已经有jQuery可以做到这一点;只是想将其纳入模型更改中

到目前为止我拥有的

HTML反馈表的相关部分(UL列表):

        <ul class="thumbnails" id="feedbackList">
            <li class="feedbackItem" id="feedbackItemPraise" title="Praise" data-bind="click: updateFeedbackType"><i class="icon-thumbs-up"></i>Praise</li>
            <li class="feedbackItem" id="feedbackItemCriticism" title="Criticism" data-bind="click: updateFeedbackType"><i class="icon-thumbs-down"></i>Criticism</li>
            <li class="feedbackItem" id="feedbackItemProblem" title="Problem" data-bind="click: updateFeedbackType"><i class="icon-warning-sign"></i>Problem</li>
            <li class="feedbackItem" id="feedbackItemQuestion" title="Question" data-bind="click: updateFeedbackType"><i class="icon-question-sign"></i>Question</li>
        </ul>

到目前为止的ViewModel(包括一些不相关的部分):

var FeedbackViewModel = function () {
    var self = this;
    self.manualEMailAddress = "MyEmail@MyProvider.com";
    self.manualApplicationName = "MyApplication";
    self.username = ko.observable($("#feedbackUsernameFromServer").val());
    self.feedbackType = ko.observable("Praise");
    self.wantsFollowUp = ko.observable(true);
    self.enteredName = ko.observable("");
    self.feedbackText = ko.observable("");
    self.userNameCaptured = ko.computed(function () { return self.username().length > 3; }, self);
    self.mailToLink = ko.computed(function () { return "mailto:" + self.manualEMailAddress + "?subject=" + encodeURIComponent(self.feedbackType()) + encodeURIComponent(" for ") + encodeURIComponent(self.manualApplicationName) + "&body=" + encodeURIComponent(self.feedbackText()) }, self);
};
var feedbackViewModel = new FeedbackViewModel();
ko.applyBindings(feedbackViewModel, document.getElementById("feedbackModal"));

当前要更改样式的jQuery(尚未链接到模型):

$("#feedbackList li").click(function () {
    $("#feedbackList li.feedbackItem-Highlighted").removeClass("feedbackItem-Highlighted");
    $(this).addClass("feedbackItem-Highlighted");
});

我认为我需要添加到ViewModel中,但不太起作用:

self.updateFeedbackType = function (elementToChangeTo) {
    self.feedbackType($(elementToChangeTo).attr("title"));
    $("#feedbackList li.feedbackItem-Highlighted").removeClass("feedbackItem-Highlighted");
    $(elementToChangeTo).addClass("feedbackItem-Highlighted");
};

这导致feedbackType变成未定义的,并且视觉变化没有发生。

我哪里错了?谢谢你的帮助!

我认为您只需要在vm的定义中使用该函数。

这里有一个似乎有效的jsfiddle:

http://jsfiddle.net/gN3HV/

更新:这是一把小提琴,它可以更好地利用淘汰赛并正确地实现目标:

http://jsfiddle.net/gN3HV/7/

elementToChangeTo返回FeedbackViewModel(与this相同),而不是单击的元素——行为与jQuery有点不同。

传递到updateFeedbackType的第二个参数将是一个事件,因此可以使用$(event.target)来获取对单击的元素的引用。

self.updateFeedbackType = function (view, event) {
    var $elementToChangeTo = $(event.target);
    self.feedbackType($elementToChangeTo.attr("title"));
    $("#feedbackList li.feedbackItem-Highlighted").removeClass("feedbackItem-Highlighted");
    $elementToChangeTo.addClass("feedbackItem-Highlighted");
};

然而,@daedalus28解决了一个更大的问题,那就是你没有利用knocket.js的优势,并且使过程过于复杂。你并不真的需要两者来解决这个简单的条件。