Me gustaría saber cómo crear un calculada observables de la matriz.

En mi opinión, modelo, tengo 2 observable matrices, y me gustaría tener un calculada observables de la matriz que es simplemente ambas matrices combinadas.

function ViewModel() {
    var self = this;
    self.listA= ko.observableArray([]);
    self.listB = ko.observableArray([]);
    self.masterList= //combine both list A and B
InformationsquelleAutor Matt Mangold | 2012-07-02

5 Comentarios

  1. 33

    Este se combinan las dos matrices y volver a la lista combinada. Sin embargo, no es un calculada observables de la matriz (no sé si eso es posible), pero una regular calculada observable.

    self.masterList = ko.computed(function() {
        return this.listA().concat(this.listB());
    }, this);
    • Yo creo que esta respuesta es errónea, para la mayoría de los casos de uso: el valor de la calculada observable es una matriz regular, no se observa un array (aproximadamente indicó en la respuesta). Por lo tanto, la actualización de listA o listB va a sustituir completamente a la matriz de sí mismo, en lugar de actualizar su contenido (que es lo que queremos en el 99% de los casos). Esto significa que usted no debe enlazar vistas a este observables. En efecto, este código es tan útil como su no-calculada variante. Ver otras respuestas para los diferentes enfoques.
    • No funciona en este caso, pero el golpe de gracia plugin de octavos de final de proyecciones implementa mucho más eficiente calculada observable matrices utilizando las bastante nuevo matriz de cambio de suscripciones. Este plugin puede ser ampliado para apoyar una eficiente concat operación.
    • cuando se utiliza como un stratergy auto.masterList.push(‘elemento’) dice que la lista no está definido. Esto se convierte en fundamental a la hora de utilizar las dependencias como ko sortable
  2. 12
    self.masterList = ko.observableArray();
    ko.computed(function () {
        self.masterList(self.listA().concat(self.listB()));
    });

    Similar a Joe Flateau la respuesta en el espíritu, pero me gusta pensar que este método es más simple.

    • Esta es la forma en que me iba a hacerlo así, pero no esta todavía sufren el problema como el aceptado contestar; en la que cualquier cambio puede provocar que el ver enlazado a la masterList a dibujar completamente?
    • Sí, este hecho se vuelve a generar el array completo, y dependiendo del motor de la vista puede o no puede volver a hacer toda la DOM subgrafo por lo que las vistas están vinculados a ella (aunque no necesariamente, podría hacer un diff y aplicarlo). Tenga en cuenta que todavía puede ser la mejor solución para evitar muchas actualizaciones. Este no es el problema que describí con respecto a la respuesta que usted menciona, en la cual si el motor de la vista capta la matriz de la propiedad en sí (como opuesta a la ruta de acceso a él), entonces nunca podría detectar que cambió la matriz (ya que no es observable), y por lo tanto nunca actualización de todo.
    • Yo estoy usando esta respuesta, por ahora, pero parece muy lento… tal vez estoy haciendo algo mal. sin embargo, ¿esta solución es romper el propósito de KO? hay otra manera de resolver el problema de la necesidad de una calculada observables de la matriz? sólo me preguntaba si esta es la herramienta adecuada para el uso en mi (o cualquier) de la situación.
    • No hay nada malo con el enfoque tanto como usted necesita combinar las listas en este orden en particular. Yo sólo se utiliza concat aquí porque todos los demás, para comparar fácilmente con otras respuestas. Si yo fuera a quitar ese requisito, probablemente voy a hacer las cosas de manera diferente (porque, de hecho, esto es lento). E. g. push/empalme elementos directamente. Si los elementos de cambio a menudo que me gustaría probable que el uso de una lista enlazada en lugar de una matriz. Tal vez usted puede hacer una pregunta por separado con sus requisitos.
  3. 9

    Sé que esto es una vieja pregunta, pero yo pensaba que iba a tirar mi respuesta:

    var u = ko.utils.unwrapObservable;
    
    ko.observableArray.fn.filter = function (predicate) {
        var target = this;
    
        var computed = ko.computed(function () {
            return ko.utils.arrayFilter(target(), predicate);
        });
    
        var observableArray = new ko.observableArray(u(computed));
    
        computed.subscribe(function (newValue) { observableArray(newValue); });
    
        return observableArray;
    };
  4. 6

    Un observableArray es sólo un observable con un poco más propiedades. Por lo tanto, un calculada observables que devuelve una matriz en la clausura será tratada como una matriz.

    • Bueno, algo así. Acabo de probar y parece que a menos que sea declarado como un observable de la matriz, métodos como el de cambio y el pop no están divididos por usted.
    • Para el beneficio de la gente como yo, encontrar esto más adelante: esto no es cierto, vea los comentarios sobre la aceptada respuesta de por qué
  5. 2

    No estoy seguro de si esta es la opción más eficiente, pero es bastante sencillo y funciona para mí. El ko.calcula devuelve un observable de la matriz de la siguiente manera:

    self.computedArrayValue = ko.computed(function() {
        var all = ko.observableArray([]);
        ....
        return all(); 
    });

    Un ejemplo del código:
    Html:

    <div data-bind="foreach: days">
        <button class="btn btn-default btn-lg day" data-bind="text: $data, click: $root.dayPressed"></button>        
    </div> 

    Función Javascript en la vista de modelo:

    self.days = ko.computed(function() {
        var all = ko.observableArray([]);
        var month = self.selectedMonth();   //observable
        var year = self.selectedYear();     //observable
        for (var i = 1; i < 29; i++) {
            all.push(i);
        }
        if (month == "Feb" && year % 4 == 0) {
            all.push(29);
        } else if (["Jan","Mar","May","Jul","Aug","Oct","Dec"].find((p) => p == month)) {
            [29,30,31].forEach((i) => all.push(i));
        } else if (month != "Feb") {
            [29,30].forEach((i) => all.push(i));                
        }
        return all(); 
    });

Dejar respuesta

Please enter your comment!
Please enter your name here