【问题标题】:Option values are empty when using data-bind=with in knockoutJs在 knockoutJs 中使用 data-bind=with 时,选项值为空
【发布时间】:2017-04-11 07:27:28
【问题描述】:

我正在使用 knockoutJs 处理选择输入下拉菜单,但在 knockoutJs 中使用 data-bind=with 时,选项值为空。谁能帮我解决这个问题。

Dropdown.html

 <span class="price"><select data-bind="options: preferedTimeToPickup,optionsCaption: 'Dont Know or Does not Matter',
    optionsText: 'name',value: preferedTimeToPickupVal" id="u3413_input" ></select>
    </span>

自定义.js

    this.preferedTimeToPickup = 
    [{name:"Morning (8-11)",price:5},
     {name:"Lunch (11-2)",price:6},
     {name:"Afternoon (2-5)",price:7},
     {name:"Specific: 8:00",price:8.5},
     {name:"Specific: 9:00",price:9.5},
     {name:"Specific: 10:00",price:10.25},
     {name:"Specific: 11:00",price:11.25},
     {name:"Specific: 12:00",price:12.25},
     {name:"Specific: 1:00",price:13.25},
     {name:"Specific: 2:00",price:14.25},
     {name:"Specific: 3:00",price:15.25},
     {name:"Specific: 4:00 (closed at 4 on sat)",price:16.25}];

     this.preferedTimeToPickupVal = ko.observable();

使用下面的html显示数据

<p data-bind="with: preferedTimeToPickupVal">
 <span data-bind="text: name"></span> 
</p>
<p data-bind="with: preferedTimeToPickupVal">
<span data-bind="text: price"></span>
</p>

到目前为止一切正常,但在选择下拉列表中value="" 为空,如果我在input type select 中使用optionsValue: 'name',则值呈现正常但data-bind="with: preferedTimeToPickupVal 无法在我想要的地方工作显示数据。

任何帮助将不胜感激。

【问题讨论】:

  • 在使用淘汰赛时不要依赖document.getElementById('id').valuevalue 绑定允许您存储的不仅仅是字符串,这在您的情况下非常有用(因为它支持具有 with 绑定的部分)。良好做法:如果您在其他地方需要value,请链接到您的视图模型。不好的做法:至少使用 ko.dataFor(element).preferedTimeToPickupVal().price 从 DOM 中检索所选价格。

标签: javascript jquery knockout.js


【解决方案1】:

Your code 工作正常,请确保您正确使用this

var vm = function () {
    this.preferedTimeToPickup = [{
        name: "Morning (8-11)",
        price: 5
      }
      //...
    ]

    this.preferedTimeToPickupVal = ko.observable()
}
ko.applyBindings(new vm());

编辑

好的,我想我明白你想要什么了。请看my updated fiddle

基本上,如果您想在select 标记中为每个option 节点添加value 属性,则必须在option 绑定中使用optionsValue: 'name' 选项。

通过这样做,您现在存储的是对象的名称属性,而不是完整的对象。您现在必须找到一种方法来获取数组中与所选值匹配的正确对象。

要做到这一点,您可以选择临时Varialbe,该临时Varialbe可容纳您的选择,以及将在选择变化时过滤阵列的计算机可观察到,并获取右侧对象。
<span class="price"><select data-bind="options: preferedTimeToPickup,
    optionsCaption: 'Dont Know or Does not Matter',
    optionsValue: 'name',
    optionsText: 'name',
    value: _preferedTimeToPickupVal" id="u3413_input" ></select>
</span>

var vm = function () {
    this.preferedTimeToPickup = [ {}, {} ]
    this._preferedTimeToPickupVal = ko.observable();
    this.preferedTimeToPickupVal = ko.pureComputed(function() {
      var selectedVal = this._preferedTimeToPickupVal()
      var defaultVal = { price: null, name: null }
      var found = null
      if (selectedVal) {
        found = this.preferedTimeToPickup.filter(function(i) {
          return i.name === selectedVal
        })
      }
      return found && found[0] ? found[0] : defaultVal
    }, this)
}

【讨论】:

  • 感谢您的回答,它工作正常,但 value="" 显示为空,在我的情况下我面临同样的问题。对于某些功能,我需要按“Id”呈现值。
  • Knockout 绕过了value 属性,因为选择是一个实际的对象引用;不是字符串。如果您使用optionsValue,它将起作用,但您需要重新计算您的选择。归根结底,必须通过 DOM 访问 value 属性表明您没有遵循淘汰赛架构指南...
  • 好的,我想我明白你想要什么了。您必须设置两件事:一个临时变量,它将存储选择的值,以及计算的 observable,它将在选择更新时过滤您的数组。查看我的更新小提琴
【解决方案2】:

您只需添加optionsValue: price 并使用pureComputed 即可根据所选值获取正确的信息。

function viewModel () {
  var self = this;      
  self.preferedTimeToPickup = [
    {name:"Morning (8-11)",price:5},
    {name:"Lunch (11-2)",price:6},
    {name:"Afternoon (2-5)",price:7},
    {name:"Specific: 8:00",price:8.5},
    {name:"Specific: 9:00",price:9.5},
    {name:"Specific: 10:00",price:10.25},
    {name:"Specific: 11:00",price:11.25},
    {name:"Specific: 12:00",price:12.25},
    {name:"Specific: 1:00",price:13.25},
    {name:"Specific: 2:00",price:14.25},
    {name:"Specific: 3:00",price:15.25},
    {name:"Specific: 4:00 (closed at 4 on sat)",price:16.25}
  ];

  self.selectedPrice = ko.observable("");    

  // use this to get the selected value object and show it on the view
  self.preferedTimeToPickupVal = ko.pureComputed(function() {
    if(self.selectedPrice() !== "")
      return ko.utils.arrayFirst(self.preferedTimeToPickup, function(time) {
        return self.selectedPrice() === time.price;
      });
    return null;
  }, this);  
}

ko.applyBindings(new viewModel()); 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<span class="price">
  <select data-bind="options: preferedTimeToPickup,optionsCaption: 'Dont Know or Does not Matter',
optionsText: 'name', optionsValue: 'price', value: selectedPrice" id="u3413_input" ></select>
</span>

  <p data-bind="with: preferedTimeToPickupVal">
    <span data-bind="text: name"></span>   
    </p>
  <p data-bind="with: preferedTimeToPickupVal">
    <span data-bind="text: price"></span>
  </p>

【讨论】:

  • 不需要需要将with 包装在if 绑定中。 with 绑定完全支持 falsey 值,它只会删除其内容。感谢您尝试提供帮助,但您可能希望在回答中对“可能是……”更加小心 :) 如果您无法找出提供的代码有什么问题,请先在 cmets 中寻求说明.
  • 感谢您的回答,它工作正常,但在此示例中 value="" 显示为空,在我的情况下我面临同样的问题。对于某些功能,我需要按“Id”呈现值。
  • @M. Ihsan,该示例未显示正确的值,请运行代码 sn-p,我的代码中也面临相同的输出。
  • 你想在值中加入什么?我把价格放在那里。
  • 我仍然面临“ReferenceError:价格未定义”,结果显示为空,未知数字为“名称:9064848”,我正在使用 magento 2 中的 requireJs 尝试此代码。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-02
  • 1970-01-01
  • 2012-05-19
  • 1970-01-01
  • 2015-09-04
  • 1970-01-01
  • 2013-12-06
相关资源
最近更新 更多