Comment partager les observables Knockout JS entre les composants de l'interface utilisateur


12

Je comprends comment utiliser imports: {}etexports: {} partager les propriétés des composants d'une interface utilisateur, telles que:

defaults: {
    exports: {
        shouldShowMessage: '${$.component}'
    }
}

Qui renvoie le nom du composant dans les exportations.

entrez la description de l'image ici

Mais lorsque j'essaie d'exporter un observable Knockout, il est toujours indéfini:

defaults: {
    exports: {
        shouldShowMessage: '${$.shouldShowMessage}'
    }
}

...

setupKoBindings: function() {
    this.shouldShowMessage = ko.observable('Testing');
}

entrez la description de l'image ici

Comme solution de contournement, je vais créer un modèle de stockage comme expliqué ici, mais je préférerais utiliser les importations et les exportations.

Réponses:


12

Les valeurs de l'objet exports doivent être résolues en un nom et une propriété d'une instance UiComponent, séparés par un «:», par exemple checkout.cart.total:title.
Le nom de la cible d'exportation doit inclure "l'espace de noms" du composant UI.

Dans votre exemple, vous définissez la valeur sur une chaîne, qui se résout en une propriété de l'UiComponent qui est la source d'exportation. L'exportation n'est pas définie lorsque vous l'inspectez car il ne s'agit pas d'une cible d'exportation valide.

Voici un exemple qui fonctionne:

defaults: {
    exportTarget: "foo.bar",
    exportTargetProperty: "showMessage",

    tracks: {
        shouldShowMessage: true
    },

    exports: {
        shouldShowMessage: '${$.exportTarget}:${$.exportTargetProperty}'
    }
}
...

Ce qui précède copiera la valeur de la shouldShowMessagepropriété dans la propriété showMessaged'un UiComponent avec le nom complet foo.barchaque fois que la valeur change.
Notez que cela ne rendra pas automatiquement la propriété cible également observable KO. Cela doit être déclaré explicitement, si les changements de valeur doivent déclencher KO pour rediriger les nœuds DOM qui accèdent à cette propriété.

Soit dit en passant, l'ajout shouldShowMessageà l' tracksobjet en fera un ko-es5 observable automatiquement. L'utilisation d'un littéral ko.observable()fonctionne aussi.

Dans l'exemple ci-dessus, le exportTargetet exportTargetPropertysont configurés dans le defaults. Ils pourraient également être spécifiés dans le cadre des options UiComponent dans le JSON, ce qui est généralement plus logique, car c'est là que la hiérarchie UiComponent comprenant les noms UiComponent est définie.

Enfin, je voudrais noter que je pense personnellement que votre solution utilisant un objet de valeur pour transmettre la valeur à l'autre composant d'interface utilisateur est meilleure que d'utiliser des exportations ou des importations. D'après mon expérience, le maintien de l'état partagé dans le DOM ou dans UiComponents est une recette de spaghetti OOP dans tous les cas, sauf les plus simples.


Excellente explication, merci @ Vinai! J'essaierai quand j'aurai le temps et je marquerai cela comme accepté si cela fonctionne.
Ben Crook

J'ai rencontré des problèmes lors de l'utilisation tracks, la souscription manuelle à observables ne fonctionne plus this.shouldShowMessage.subscribe is not a functionlors de l'utilisation. this.shouldShowMessage.subscribe(function() { ... }); Cela fonctionne bien lors de la configuration des observables de toute autre manière. Sent comme si je manque une étape ou tracksne crée pas un observable de la même manière.
Ben Crook

Vous avez raison, les propriétés ne sont plus des observables ko réguliers, juste des paires getter / setter ES5. Si vous souhaitez accéder à la fonction observable d'origine, vous pouvez injecter ko et utiliser ko.getObservable(this, 'shouldShowMessage').subscribe(function(newValue) { ...});(le premier argument est le viewmodel ( this), le second le nom de la propriété suivie. Plus d'infos ici: github.com/SteveSanderson/knockout-es5
Vinai

Ahh c'est logique, vous êtes le meilleur <3
Ben Crook

1
Après avoir joué avec les importations et les exportations et toujours en échec, je suis d'accord que c'est du code spaghetti, j'ai abandonné et je m'en tiendrai aux abonnements manuels et à un modèle de stockage.
Ben Crook
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.