【问题标题】:KnockoutJS Add and Loop ObservablesKnockoutJS 添加和循环 Observables
【发布时间】:2015-03-04 19:43:05
【问题描述】:

嗨,伙计,我一直在努力解决这个问题,但我是 KnockoutJS 的菜鸟。这个想法是您添加一个输入,然后它接下来会显示自己的设置,例如名称 attr 占位符、必需等,但我遇到了几个问题。

我已经设法让一些工作,但由于某种原因 required 总是正确的。我遇到的另一个问题是添加更多 - 我是否正确地说我需要在 js 中添加更多可观察对象?我可以不做某种循环吗?这是我的代码,请帮忙。

<div class="input-row">
  <div class="input-item">            
     <input type="text" data-bind="attr: { name: itemName, placeholder: itemPlaceholder, value : itemValue, required : itemRequired }" />         
  </div>
  <div class="input-settings">
    name:
    <input type="text" data-bind="value: itemNameSetting">
    <br/>

    placehoder:
    <input type="text" data-bind="value: itemPlaceholderSetting">
    <br/>

    required:
    <select data-bind="value: itemRequiredSetting">
      <option value="true">true</option>
      <option value="false">false</option>
    </select>
    <br/>   

    maxlength:
    <br/>

    defaultvalue:
    <input type="text" data-bind="value: itemValueSetting">
    <br/>
  </div>
</div>
<button>+ ADD MORE INPUTS</button>

JS

var ViewModel = function() {
    this.itemNameSetting        = ko.observable(); 
    this.itemPlaceholderSetting = ko.observable();
    this.itemRequiredSetting    = ko.observable();
    this.itemValueSetting       = ko.observable();

    this.itemName = ko.pureComputed(function() {            
        return this.itemNameSetting();
    }, this);

    this.itemPlaceholder = ko.pureComputed(function() {           
        return this.itemPlaceholderSetting();
    }, this);

    this.itemRequired = ko.pureComputed(function() {
      return this.itemRequiredSetting();         
    }, this);

    this.itemValue = ko.pureComputed(function() {           
        return this.itemValueSetting();
    }, this);
};

ko.applyBindings(new ViewModel());

【问题讨论】:

  • 你为什么用pureComputed复制每个...Setting observable?
  • 正如我所说,我对此完全陌生,这个想法是动态添加更多输入,旁边有自己的一组设置。
  • “嗯,这似乎是个好主意”是完全有效的 :) 我可能从你的代码示例中看不到另一个原因,所以问一下也无妨。跨度>

标签: javascript knockout.js


【解决方案1】:

你的这个东西有多个属性——一个名字、一个占位符、一个值等等:

{
  name: 'foo',
  placeholder: 'foo goes here',
  value: 'bar'
}

但是你需要很多。在 Javascript 中,一个很好的方法是构建一个构造函数:

var InputItem = function InputItem(name, placeholder, value) {
  this.name        = name;
  this.placeholder = placeholder;
  this.value       = value;
}

现在我们可以随心所欲地制作它们:

var item1 = new InputItem('foo', 'foo goes here', 'bar');
var item2 = new InputItem('bar', 'bar goes here', 'baz');

item1.placeholder
// returns 'foo goes here'
item2.name
// returns 'bar'
item2.value = 'something else'
// item 2's value is now changed to 'something else'

但由于这是 Knockout,我们希望我们的属性是可观察的:

var InputItem = function InputItem(name, placeholder, value) {
  this.name        = ko.observable(name);
  this.placeholder = ko.observable(placeholder);
  this.value       = ko.observable(value);
}

var item1 = new InputItem('foo', 'foo goes here', 'bar');
item1.name()
// returns 'foo'
item1.placeholder('kittens')
// item 1's placeholder is now changed to 'kittens'

您在这里拥有的是一个数据模型 - 包含单个“事物”所需的所有数据,在您的案例中是一个输入。现在我们需要一个包含所有数据模型的视图模型,以及一种让用户添加更多数据模型的方法:

var ViewModel = function ViewModel() {
  var that = this;

  this.inputItems = ko.observableArray([]);

  this.addInput = function addInput() {
    that.inputItems.push( new InputItem() );
  };
}

ko.applyBindings( new ViewModel() );

在我们的标记中,我们使用foreach 遍历可观察的inputItems 数组中的所有InputItems

<div data-bind="foreach: inputItems">
  <!-- everything inside here is rendered once for every InputItem -->
  <input type="text" data-bind="value: name">
  <input type="text" data-bind="value: placeholder">
</div>

<button data-bind="click: addInput">Add another input</button>

试试这个交互式演示:

var InputItem = function InputItem(name, placeholder, value) {
  this.name        = ko.observable(name);
  this.placeholder = ko.observable(placeholder);
  this.value       = ko.observable(value);
}

var ViewModel = function ViewModel() {
  var that = this;

  this.inputItems = ko.observableArray([]);

  this.addInput = function addInput() {
    that.inputItems.push(new InputItem());
  };
}

ko.applyBindings(new ViewModel());
.console {
  background-color: lightgrey;
  padding: 1rem;
  margin-top: 1rem;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<ul data-bind="foreach: inputItems">
  <li>
    <!-- everything inside here is rendered once for every InputItem -->
    <input type="text" data-bind="value: name" placeholder="input name">
    <input type="text" data-bind="value: placeholder" placeholder="input placeholder">
  </li>
</ul>

<button data-bind="click: addInput">Add another input</button>

<div class="console">
  <h1>You have added <span data-bind="text: inputItems().length"></span> input items</h1>
  <ul data-bind="foreach: inputItems">
    <li>
      Name: <span data-bind="text: name"></span> with placeholder <span data-bind="text: placeholder"></span>
    </li>
  </ul>
</div>

【讨论】:

  • 非常感谢 Janfoeh,它 100% 有效。我已经稍微修改了我的代码,它再次很棒。最后一个问题。当我添加禁用或必需的 attr 时,它在设置为 true 时起作用,但是当我将其设置为 false 时,attr 似乎保持不动,并且没有根据淘汰赛文档删除,它只是将其设置为 false。有什么想法吗?
  • requireddisabled 输入属性对 Knockout 数据绑定没有影响 - 仅当您将表单提交到服务器时才有效。 required 表示没有该字段无法提交表单,disabled 表示无法与之交互,并且其值不会发送到服务器。由于您没有提交表单,因此它们无效。如果您需要更多帮助,请提出另一个问题。
  • 嗨 Janfoeh,新问题位于此处stackoverflow.com/questions/28854840/…
猜你喜欢
  • 2015-06-22
  • 2016-05-30
  • 2019-06-17
  • 2014-10-23
  • 2021-06-03
  • 2013-07-19
  • 2014-01-22
  • 1970-01-01
  • 2020-04-07
相关资源
最近更新 更多