【问题标题】:How to pass element to javascript function and access the first child如何将元素传递给javascript函数并访问第一个孩子
【发布时间】:2016-09-26 00:02:18
【问题描述】:

我在 C# 文件后面的 ASP.NET 代码中创建复选框。我在将控件添加到页面之前添加了一个属性值,因此 ASP 正在将该属性添加到复选框和文本标签周围的跨度中。它看起来像这样:

<span data-bind="visible: showCheckBox(this)">
   <input id="" type="checkbox" name="ctl00$MainContent$SecondaryForm$ctl00" value="1">    
   <label for="">Outside Source</label>
</span>

我有一个用 Knockout.js 编写的名为 showCheckBox() 的函数。它根据紧接其前面的下拉列表中所选项目的值确定是否应显示目标复选框。例如,如果下拉列表中选定项的值为 1,则对应值为 1 的目标复选框将可见。该函数如下所示:

function showCheckBox(span) {
   var value = span.firstChild.value;
   return value == reason();  
}

reason() 是视图模型变量,它保存所选下拉列表项的值。 无论我做什么,我都无法正确发送复选框的值。它始终是未定义的。

【问题讨论】:

  • 对不起,我有点困惑。你到底在纠结哪个价值观? span.firstChild 未定义?还是span.firstChild.valuespan 究竟是什么 DOM 对象?
  • 也许我很遥远,但我正在使用“this”关键字将 span DOM 元素发送到函数。然后我尝试提取复选框的值并返回它与 reason() 视图模型变量的比较结果
  • 我对knockout不是很熟悉,但是你调试过这段代码吗?我不完全确定 span 是你所期望的
  • 你能在 plnkr 中说明问题吗?尝试记录传入的跨度变量。

标签: javascript c# asp.net knockout.js


【解决方案1】:

问题是隐藏的,这是因为您在很大程度上根本没有使用 KnockoutJS。你应该检查the KnockoutJS checked binding的文档。

应该很可能没有理由检查视图模型中的 DOM,即使是那些处理可见性的模型。相反,请使用 视图模型。您还没有完全发布完整的最小复制,但它或多或少应该是这样的:

function ViewModel() {
  var self = this;
  
  self.reasons = [{id: 1, txt: "Main reason"}, {id: 2, txt: "Other reason"}];
  self.reason = ko.observable(self.reasons[0]);
  
  self.showCheckBox = ko.computed(function() {
    return self.reason().id === 1;
  });
  
  self.hasOutsideSource = ko.observable(false);
};

ko.applyBindings(new ViewModel());
pre { font-family: consolas; background: smoke; border: 1px solid #ddd; padding: 5px; margin: 5px; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<select data-bind="options: reasons, value: reason, optionsText: 'txt'"></select>

<span data-bind="visible: showCheckBox">
  <label> 
    <input data-bind="checked: hasOutsideSource" type="checkbox" name="ctl00$MainContent$SecondaryForm$ctl00" value="1">    
     Outside Source
  </label>
</span>

<hr>
This would be sent to your server / debug info:
<pre data-bind="text: ko.toJSON($root, null, 2)"></pre>

如果您不能采用上述方法,我强烈建议您考虑跳过使用 KnockoutJS,因为如果您自己进行大量 DOM 操作,它可能会给您带来更多的麻烦。

【讨论】:

    【解决方案2】:

    这个 HTML 中的第一个子元素实际上是 textNode,如果找到它,firstChild 将返回它。这些是它返回的实际字符:"↵ "(回车和空格)。

    您可以改用firstElementChild 属性:

    function showCheckBox(span) {
        var value = span.firstElementChild.value;
        return value == reason();  
    }
    

    另外,不要忘记查看firstElementChild 的支持表。

    【讨论】:

    • 在控制台中它仍然说值未定义。在考虑了几个小时后,我的同事提出了一个对我有用的解决方案。如果你愿意看的话,我把它贴在下面。感谢您抽出宝贵时间提供帮助!
    • 嗯,这真的很奇怪,因为它对我有用。很高兴你找到了解决方案!
    【解决方案3】:

    也考虑了一段时间,有同事提出了这个解决方案。

    他建议我不要将复选框的值分配为与下拉列表视图模型变量对应的 ID,而是将其分配在 data-bind 属性中。在我的 C# 代码隐藏文件中,看起来像这样

    cb.Attributes.Add("data-bind", String.Format("visible: showCheckBox({0})", reasonDetails[i].ReasonForSendingNoticeID.ToString()));
    

    在 HTML 中显示时的样子

    <span data-bind="visible: showCheckBox(1)" style="display: none;">
    <input id="" type="checkbox" 
    name="ctl00$MainContent$SecondaryForm$ctl00" value="Outside Source">
    <label for="" style="display: inline;">Outside Source</label>
    </span>
    

    然后我把函数改成如下

    function showCheckBox(id) {
        return id == reason();
    }
    

    这样做允许我们直接将值传递给函数,而无需传递元素或其子元素。

    感谢您的帮助和建议。

    【讨论】:

      猜你喜欢
      • 2020-11-24
      • 2014-11-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-20
      • 1970-01-01
      相关资源
      最近更新 更多