将数组值分配给knockoutjs中的变量

时间:2016-11-17 06:30:01

标签: javascript knockout.js

我想将一个数组值分配给knockoutjs中的变量。 我可以通过for循环迭代一个数组。我的代码是

<!-- ko foreach: {data: friends, as: 'friend'} --> 
<span data-bind="text:friend"></span> 
<!-- /ko -->

<script type="text/javascript">

    var viewModel = {
        firstname: ko.observable("X"),
        lastname: ko.observable("Y"),
        friends: ko.observableArray(["A", "B"]),
        books: ko.observableArray(["Book1", "Book2"]),
    };
    viewModel.fullname = ko.dependentObservable(function () {
        return this.firstname() + " " + this.lastname();
    }, viewModel);
    ko.applyBindings(viewModel); 
</script>

但我想要书的第一个元素,然后迭代朋友。像

<!-- ko {books()[0], as : 'book'} -->
<!-- ko foreach: {data: friends, as: 'friend'} -->

<span data-bind="text:friend"></span>
<span data-bind="text:book"></span>

<!-- /ko -->
<!-- /ko -->

我知道我的做法是错误的。但我无法弄清楚如何获得第一本书的元素,然后通过朋友进行迭代。

1 个答案:

答案 0 :(得分:1)

三种方法:

  1. 创建自定义绑定以将内容添加到绑定上下文
  2. 为您的朋友书组合创建新的视图模型
  3. 使用$parent$root关键字,不允许您定义新的变量名称
  4. 1。使用自定义绑定

    基于this示例,您可以扩展绑定上下文。请注意,foreach也会创建新的绑定上下文,因此您仍然必须使用$parent。您还可以扩展标准foreach绑定以包含用于扩展绑定上下文的额外参数(以摆脱$parent)。

    &#13;
    &#13;
    var viewModel = {
      firstname: ko.observable("X"),
      lastname: ko.observable("Y"),
      friends: ko.observableArray(["A", "B"]),
      books: ko.observableArray(["Book1", "Book2"]),
    };
    
    ko.bindingHandlers.withProperties = {
        init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
            // Make a modified binding context, with a extra properties, and apply it to descendant elements
            var innerBindingContext = bindingContext.extend(valueAccessor);
            ko.applyBindingsToDescendants(innerBindingContext, element);
     
            // Also tell KO *not* to bind the descendants itself, otherwise they will be bound twice
            return { controlsDescendantBindings: true };
        }
    };
    ko.virtualElements.allowedBindings.withProperties = true;
    ko.applyBindings(viewModel);
    &#13;
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
    
    <!-- ko foreach: { data: friends, as: 'friend' } -->
    <!-- ko withProperties: { book: $parent.books()[0] } -->
    <span data-bind="text:friend"></span>
    <span data-bind="text:book"></span>
    <!-- /ko -->
    <!-- /ko -->
    &#13;
    &#13;
    &#13;

    2。创建新的视图模型

    我认为这是&#34;最纯粹的&#34; viewmodel - 查看解决方案。

    &#13;
    &#13;
    var viewModel = {
      firstname: ko.observable("X"),
      lastname: ko.observable("Y"),
      friends: ko.observableArray(["A", "B"]),
      books: ko.observableArray(["Book1", "Book2"]),
    };
    
    viewModel.bookFriendCombos = ko.pureComputed(function() {
      var book = viewModel.books()[0];
      return viewModel.friends().map(function(friend) {
          return {
            friend: friend,
            book: book
          };  
      });
    });
    
    
    ko.applyBindings(viewModel);
    &#13;
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
    
    <!-- ko foreach: bookFriendCombos -->
    <span data-bind="text:friend"></span>
    <span data-bind="text:book"></span>
    <!-- /ko -->
    &#13;
    &#13;
    &#13;

    3。使用$parent

    可能最容易实施,只要您的观点仍然简单,我就更喜欢这个。

    &#13;
    &#13;
    var viewModel = {
      firstname: ko.observable("X"),
      lastname: ko.observable("Y"),
      friends: ko.observableArray(["A", "B"]),
      books: ko.observableArray(["Book1", "Book2"]),
    };
    viewModel.fullname = ko.dependentObservable(function() {
      return this.firstname() + " " + this.lastname();
    }, viewModel);
    ko.applyBindings(viewModel);
    &#13;
    <script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
    
    <!-- ko foreach: {data: friends, as: 'friend'} -->
    <span data-bind="text:friend"></span>
    <span data-bind="text:$parent.books()[0]"></span>
    <!-- /ko -->
    &#13;
    &#13;
    &#13;