2016-07-26 4 views
0

Als Lernübung habe ich eine ToDo-Liste mit Aufgaben. Aus meiner Sicht möchte ich die Artikel nach Abschluss sortiert anzeigen. Unten ist mein Ansichtsmodell. Wie würde ich vorgehen, was ich erreichen möchte? Wie richte ich die berechneten Observablen ein?Wie berechne ich 2 Listen basierend auf der Eigenschaft eines Listenobjekts in Knockout?

  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) 
      ]),    
     ]); 
    } 

Antwort

1
  1. Erstellen einer berechneten Eigenschaft in Ihrem TodoList Ansichtsmodell. Da das Verfahren der berechnete keine Nebenwirkungen hat, ist es am besten, einen ko.pureComputed zu verwenden:

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

Hinweis: die zweiten this Parameter setzen den aktuellen this Kontext als „Eigentümer“ des berechnet. Das heißt, innerhalb der berechneten Methode bezieht sich this auf die TodoList Instanz.

  1. Innerhalb der Methode des berechneten bewerten todoItems beobachtbaren Array ein Abonnement für seine Werte zu schaffen:

    var currentItems = this.todoItems(); 
    
  2. Filter Einzelteile durch completed und schicken Sie das Array:

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

Nun hat jedes TodoList eine berechnete Array von complet ed items. Sie könnten eine Liste unvollständiger Elemente auf ähnliche Weise erstellen.

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

Alle Code zusammen:

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); 
} 
+0

danken Ihnen für Ihre Hilfe – lee23

0

Sie

Wenn Sie noch einen Schritt weiter gehen wollen und Gruppe abgeschlossen Elemente zwischen den Listen können Sie eine ko.pureComputed zu Ihrem TodoListViewModel auch hinzufügen Definition der berechneten Observablen:

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 -->

Verwandte Themen