Nouvelle instance du modèle de vue Durandal reflétant toujours les valeurs précédentes

StackOverflow https://stackoverflow.com//questions/21012712

  •  21-12-2019
  •  | 
  •  

Question

J'ai rencontré un problème étrange en essayant un scénario de composition légèrement complexe utilisant Durandal.

Je souhaite composer dynamiquement le contenu de chaque cellule d'un tableau.A titre d'exemple, j'ai les fichiers suivants :

Welcome.html => contient le code pour restituer dynamiquement le tableau HTML

<table>
    <thead>
        <tr data-bind="foreach: columnNames">
            <th><span data-bind="text: $data"></span>

            </th>
        </tr>
    </thead>
    <tbody data-bind="foreach: items">
        <tr data-bind="foreach: $parent.columnNames">
            <!-- <td data-bind="text: $parent[$data]"></td>-->
            <td data-bind="compose: { model: $root.activeView($index), activationData: $root.activationData($parentContext.$index), cacheViews: false }"></td>
        </tr>
    </tbody>
</table>

bienvenue.js => le modèle de vue correspondant

define(['knockout'], function (ko) {
var ctor = function () {
    var m_items = [{
        'Name': 'John',
        'Age': 25
    }, {
        'Name': 'Morgan',
        'Age': 26
    }];
    this.items = ko.observableArray(m_items);
    this.columnNames = ko.computed(function () {
        if (m_items.length === 0)
            return [];
        var props = [];
        var obj = m_items[0];
        for (var name in obj)
            props.push(name);
        return props;
    });

    this.activeView = function (index) {
        if (index() == 0)
            return "viewmodels/cell-1";
        else
            return "viewmodels/cell-2";
    };

    this.activationData = function (rowIndex) {
        return m_items[rowIndex()];
    }

};

return ctor;
});

cell-1.html => vue à afficher pour la première colonne

<span data-bind="text : Name"></span>

cell-1.js => modèle de vue correspondant pour la cellule-1

define(['knockout'], function (ko) {
var model = null;
var name = ko.observable();
var ctr = function () {
    this.Name = name;
    this.activate = function (modelObject) {
        model = modelObject;
        name(model.Name);
    };
};
return ctr;
});

Et de même, une vue et un modèle de vue pour la cellule-2.

Le problème auquel je suis confronté est que même si la composition fonctionne correctement et que la fonction d'activation est appelée deux fois pour cell-1.js (une fois pour chaque ligne), la valeur de l'observable name contiendrait la valeur précédente. (c'est-à-direla valeur serait "John" lorsqu'il essaie de la définir sur "Morgan").C'est étrange car cell-1.js renvoie un constructeur et Durandal aurait donc dû créer une autre instance du modèle de vue.Pour résumer, cela se traduit par des lignes contenant les mêmes données.

Je suis sûr qu'il y a quelque chose de mineur que je dois modifier pour que cela fonctionne, mais tous mes efforts ont été vains.

Toute aide serait grandement appréciée.

Était-ce utile?

La solution

Le problème c'est que vous avez déclaré votre model et name variables au niveau du module dans votre cell-1.js.

Ainsi, même si vous renvoyez un constructeur qui est appelé deux fois, le module lui-même n'est chargé qu'une seule fois, vos modèles de vue partagent donc le même état.

Pour le résoudre, il vous suffit de déplacer vos variables à l'intérieur du ctr:

define(['knockout'], function (ko) {

var ctr = function () {
    var model = null;
    var name = ko.observable();

    this.Name = name;
    this.activate = function (modelObject) {
        model = modelObject;
        name(model.Name);
    };
};
return ctr;
});
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top