Jak udostępniać obserwowalne wyniki Knockout JS między komponentami interfejsu użytkownika

12

Rozumiem, jak używać imports: {}iexports: {} udostępniać właściwości składników interfejsu użytkownika, takie jak:

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

Która zwraca nazwę komponentu w eksporcie.

wprowadź opis zdjęcia tutaj

Ale kiedy próbuję wyeksportować obserwowalność Nokaut, zawsze jest ona niezdefiniowana:

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

...

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

wprowadź opis zdjęcia tutaj

Aby obejść ten problem, stworzę model pamięci masowej, jak wyjaśniono tutaj, ale wolałbym używać importu i eksportu.

Ben Crook
źródło

Odpowiedzi:

12

Wartości obiektu eksportu muszą zostać przetłumaczone na nazwę i właściwość instancji UiComponent, na przykład oddzielone znakiem „:” checkout.cart.total:title.
Nazwa celu eksportu musi zawierać komponent interfejsu użytkownika „przestrzeń nazw”.

W twoim przykładzie ustawiono wartość na ciąg znaków, który jest tłumaczony na właściwość UiComponent, który jest źródłem eksportu. Eksport jest niezdefiniowany podczas inspekcji, ponieważ nie jest to prawidłowy cel eksportu.

Oto przykład, który działa:

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

    tracks: {
        shouldShowMessage: true
    },

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

Powyższe spowoduje skopiowanie wartości shouldShowMessagewłaściwości do właściwości showMessageUiComponent z pełną nazwą przy foo.barkażdej zmianie wartości.
Zauważ, że nie spowoduje to automatycznie, że właściwość target będzie również możliwa do zaobserwowania KO. Należy to wyraźnie zadeklarować, jeśli zmiany wartości powinny spowodować, że KO ponownie wyśle ​​węzły DOM, które uzyskują dostęp do tej właściwości.

Nawiasem mówiąc, dodanie shouldShowMessagedo tracksobiektu sprawi, że będzie ko-es5 obserwowalny automatycznie. Używanie również dosłownych ko.observable()dzieł.

W powyższym przykładzie exportTargeti exportTargetPropertysą skonfigurowane w defaults. Można je również określić jako część opcji UiComponent w JSON, co zwykle ma większy sens, ponieważ tutaj definiuje się hierarchię UiComponent, w tym nazwy UiComponent.

Na koniec chciałbym zauważyć, że osobiście uważam, że twoje rozwiązanie wykorzystujące obiekt wartości do przekazania wartości do innego komponentu interfejsu użytkownika jest lepsze niż używanie eksportu lub importu. Z mojego doświadczenia wynika, że ​​utrzymywanie stanu współdzielonego w DOM lub w UiComponents to przepis na OOP spaghetti we wszystkich, oprócz najprostszych przypadkach.

Vinai
źródło
Doskonałe wyjaśnienie, dzięki @ Vinai! Spróbuję, kiedy będę miał czas, i oznaczy to jako zaakceptowane, jeśli zadziała.
Ben Crook
Wystąpiły pewne problemy podczas używania tracks, ręczne subskrybowanie obserwowalnych nie działa już this.shouldShowMessage.subscribe is not a functionpodczas korzystania. this.shouldShowMessage.subscribe(function() { ... });Działa dobrze, gdy ustawiasz obserwowalne w inny sposób. Wydaje mi się, że brakuje mi kroku lub tracksnie tworzy obserwowalnego w ten sam sposób.
Ben Crook,
Masz rację, właściwości nie są już zwykłymi obserwowalnymi ko, tylko pary getter / setter ES5. Jeśli chcesz uzyskać dostęp do oryginalnej obserwowalnej funkcji, możesz wstrzyknąć ko i użyć ko.getObservable(this, 'shouldShowMessage').subscribe(function(newValue) { ...});(pierwszy argument to viewmodel ( this), drugi to nazwa śledzonej właściwości. Więcej informacji tutaj: github.com/SteveSanderson/knockout-es5
Vinai
Ach, to ma sens, jesteś najlepszy <3
Ben Crook
1
Po zabawie z importem i eksportem i wciąż nie udaje mi się zgodzić, że to kod spaghetti, zrezygnowałem i pozostanę przy ręcznych subskrypcjach i modelu przechowywania.
Ben Crook