【问题标题】:Knockout js loop up to a valueKnockout js循环到一个值
【发布时间】:2018-04-13 21:42:54
【问题描述】:

我有一个可观察的整数,pages,我想循环到 html 中页面的值,例如。

pages = ko.observable(3) 

生产

<ul>
<li>1</li>
<li>2</li>
<li>3</li>
</ul> 

是否有适合此的绑定?

【问题讨论】:

    标签: knockout.js


    【解决方案1】:

    你可以这样写:

    <ul data-bind="foreach: new Array(pages())">
        <li data-bind='text: $index()+1'></li>
    </ul> 
    

    这是工作小提琴:http://jsfiddle.net/L8Uy5/

    【讨论】:

    • 不错的答案,我想要一个更复杂的答案,ko.computed。完全忘记了 $index 属性!
    • 谢谢。我认为在大多数情况下,最好使用计算,因为可以更好地控制项目。但是对于这种情况,我的变体更方便。
    • 这是一个聪明的解决方案。谢谢!
    【解决方案2】:

    如果你只需要一个简单的for 循环,你可以这样做:

    <select name="something"
        data-bind="foreach: new Array(10)">
        <option data-bind="text: $index()+1, value: $index()+1"></option>
    </select>
    

    您可以通过将(10) 替换为任意数字来指定项目数。 这将生成一个简单的下拉列表,其中包含从 1 到 10 的数字。

    【讨论】:

      【解决方案3】:

      The answer by Artem Vyshniakov 是一种在视图中运行而不更改视图模型的快速方法。但是,如果您希望快速扩展设置,或者只是不喜欢在您看来拥有(可以说是可单元测试的逻辑)new Array(pages()),这里有一个替代解决方案。另一个好处可能是您还可以封装$index + 1 位:

      function ViewModel() {
        var self = this;
        
        self.pages = ko.observable(3);
        
        self.pageArray = ko.computed(function() {
          var list = [];
          var length = parseInt(self.pages(), 10); // the <input> makes `pages` a string!
          for (var i = 1; i <= length; i++) {
            list.push(i);
          }
          return list;
        });
      }
      
      ko.applyBindings(new ViewModel());
      <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
      
      <input data-bind="textInput: pages" type="number">
      
      <ul data-bind="foreach: pageArray">
        <li data-bind="text: $data"></li>
      </ul>

      pageArray 代码主要是庞大的,因为 (a) pages 由于输入而变成字符串,这可能通过将 pages 变为可写计算来更好地解决,以及 (b) 因为我选择使用用于创建范围的for 循环/基本 解决方案(在此基础上you could improve)。

      这是一个在两个方面都有改进的建议版本:

      function ViewModel() {
        var self = this, 
            _pages = ko.observable(3);
        
        self.pages = ko.computed({
          read: () => _pages(),
          write: newVal => _pages(parseInt(newVal, 10))
        });
        
        self.pageArray = ko.computed(() => _.range(1, _pages() + 1));
      }
      
      ko.applyBindings(new ViewModel());
      <script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.8.3/underscore-min.js"></script>
      <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
      
      <input data-bind="textInput: pages" type="number">
      
      <ul data-bind="foreach: pageArray">
        <li data-bind="text: $data"></li>
      </ul>

      无论如何,pageArray 及其内容现在完全可以进行单元测试,并且可供其他视图模型逻辑位访问。 (如果你不需要那个,例如你只是在搭建一个视图,我会说选择另一个答案)。

      【讨论】:

        【解决方案4】:

        它不适用于更新字段

        你可以这样写:

        这是工作小提琴:http://jsfiddle.net/L8Uy5/

        这个效果更好https://jsfiddle.net/L8Uy5/54/

        function ViewModel(){
            var self = this;
            self.pages = ko.observable(3);
            self.virtual_elements = ko.computed(function(){
                var arr = [];
                for (var i=1; i<=self.pages(); i++) {
                    arr.push('some');
                }
                return arr;
            });
        }
        
        ko.applyBindings(new ViewModel());
        <input data-bind="value: pages"/>
        <ul data-bind="foreach: virtual_elements">
            <li data-bind='text: $index()+1'></li>
        </ul> 

        【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-10-12
        • 1970-01-01
        • 1970-01-01
        • 2013-07-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-07
        相关资源
        最近更新 更多