0

学習演習として、to do 項目を含む todo リストがあります。私の見解では、完了ごとにグループ化されたアイテムを表示したいと思います。以下は私のビューモデルです。達成したいことをどのように実行しますか、計算されたオブザーバブルをどのようにセットアップしますか?

         function TodoList(name, items) {
        this.name = ko.observable(name === "undefined"? "": name);
        this.todoItems = ko.observableArray(typeof (items) !== "undefined" ? items : []); 
    }

    function TodoItem(name,completed) {
        this.name = ko.observable(name === "undefined" ? "" : name);
        this.completed = ko.observable(completed === "undefined" ? false : completed);
    }

    function TodoListViewModel() {
        var self = this;
        self.todoLists = ko.observableArray([

            new TodoList("Groceries", [
                new TodoItem("Milk", true),
                new TodoItem("Bread",false),
                new TodoItem("Tissues",false)
            ]),
            new TodoList("Luggage", [
                new TodoItem("Hairdryer", false),
                new TodoItem("Toothbrush",false)
            ]),             
        ]);
    }
4

2 に答える 2

1
  1. ビューモデルで計算されたプロパティを作成しますTodoList。計算されたメソッドには副作用がないため、次を使用することをお勧めしますko.pureComputed

    this.completedItems = ko.pureComputed(function() { /* ... */ }, this);
    

: 2 番目のthisパラメーターは、現在のthisコンテキストを計算済みの「所有者」として設定します。つまり、計算されたメソッド内でthis、インスタンスを参照しTodoListます。

  1. 計算されたメソッド内で、監視todoItems可能な配列を評価して、その値へのサブスクリプションを作成します。

    var currentItems = this.todoItems();
    
  2. 項目をフィルタリングしcompletedて配列を返します。

    return currentItems.filter(function(item) {
      return item.completed();
    });
    

これで、everyTodoListには完了したアイテムの計算された配列が含まれます。同様の方法で、未完了の項目のリストを作成できます。

さらに一歩進んで、完了した項目をリスト間でグループ化したい場合は、次のように を追加することもできko.pureComputedますTodoListViewModel

this.allCompletedItems = ko.pureComputed(function() {
  return this.todoLists()
    .map(function(todoList) { return todoList.completedItems(); })
    .reduce(function(result, itemList) { return result.concat(itemList); }, []);
}, this);

すべてのコードを一緒に:

function TodoList(name, items) {
  this.name = ko.observable(name === "undefined" ? "" : name);
  this.todoItems = ko.observableArray(typeof(items) !== "undefined" ? items : []);

  this.completedItems = ko.pureComputed(function() {
    return this.todoItems()
      .filter(function(item) {
        return item.completed();
      });
  }, this);
}

function TodoItem(name, completed) {
  this.name = ko.observable(name === "undefined" ? "" : name);
  this.completed = ko.observable(completed === "undefined" ? false : completed);
}

function TodoListViewModel() {
  this.todoLists = ko.observableArray([
    new TodoList("Groceries", [
      new TodoItem("Milk", true),
      new TodoItem("Bread", false),
      new TodoItem("Tissues", false)
    ]),
    new TodoList("Luggage", [
      new TodoItem("Hairdryer", false),
      new TodoItem("Toothbrush", false)
    ]),
  ]);

  this.allCompletedItems = ko.pureComputed(function() {
    return this.todoLists()
      .map(function(todoList) {
        return todoList.completedItems();
      })
      .reduce(function(result, itemList) {
        return result.concat(itemList);
      }, []);
  }, this);
}
于 2016-07-26T09:28:05.880 に答える
0

計算されたオブザーバブルを定義する必要があります。

    self.completedItems = ko.computed(function() {
      return self.todoLists().reduce(function(result, list) {
         return result.concat(list.todoItems().filter(function(i) { return i.completed(); }));
      }, []);
    });

         function TodoList(name, items) {
        this.name = ko.observable(name === "undefined"? "": name);
        this.todoItems = ko.observableArray(typeof (items) !== "undefined" ? items : []); 
    }

    function TodoItem(name,completed) {
        this.name = ko.observable(name === "undefined" ? "" : name);
        this.completed = ko.observable(completed === "undefined" ? false : completed);
    }

    function TodoListViewModel() {
        var self = this;
        self.todoLists = ko.observableArray([

            new TodoList("Groceries", [
                new TodoItem("Milk", true),
                new TodoItem("Bread",false),
                new TodoItem("Tissues",false)
            ]),
            new TodoList("Luggage", [
                new TodoItem("Hairdryer", true),
                new TodoItem("Toothbrush",false)
            ]),             
        ]);
          
        self.completedItems = ko.computed(function() {
          return self.todoLists().reduce(function(result, list) {
             return result.concat(list.todoItems().filter(function(i) { return i.completed(); }));
          }, []);
        });
    }
    
    ko.applyBindings(new TodoListViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>

<!-- ko foreach: completedItems -->
<div data-bind="text: name"></div>
<!-- /ko -->

于 2016-07-26T09:33:20.680 に答える