Próbuję zrobić klasę bazową dla wszystkich moich ViewModels więc na przykład można sprawdzić „isDirty” na korzeniu-VM i go sprawdzić całą drzewo VMS (unikając wzajemnie od siebie zależnych).Odroczona ocena wszystkich obliczonych właściwości w Knockout?
Kiedy robi to zdałem sobie sprawę, że kolejność KO-właściwościach jest bardzo ważne, ponieważ nieruchomość komputerowej skonfigurować jego zapisów w oparciu o jakie inne właściwości istnieje w momencie tworzenia obiektu. Tak więc, jeśli umieściłbym obliczenie typu "tak", jak ten poniżej w klasie bazowej, to zawsze zainicjowałoby to zanim właściwości, które są zależne, nawet istnieją. W każdym razie, żeby to krótko skrócić, zauważyłem, że mogłem użyć deferEvaluation, aby zaradzić temu problemowi.
Moje pytanie to:
Czy są jakieś wady korzystania deferEvaluation wszystkich obliczonych właściwości? Dlaczego to zachowanie nie jest domyślnie prawdziwe? Kiedy powinienem go ustawić na false?
Mogę to zrobić isDirty-nieruchomość lepiej? Jakieś sugestie, jak poprawić lub zrobić to w jakiś inny sposób?
I alternatywnie, czy jest jakiś sposób, aby wyraźnie wyłączyć inicjalizacji obliczonych własności do całego obiektu jest tworzonych z wszystkimi jego właściwościami, a następnie uruchomić go w jakiś sposób. Chodzi mi o to, że jedynym problemem dla mnie jest to, że subskrypcje są ustawione zanim wszystkie właściwości są na miejscu.
Uwaga: Używam KO Lite Narzędzia do brudnej śledzenia
function ViewModel() {
var self = this;
self.isDirty = ko.computed(function() {
for (var p in self) {
if (self[p].isDirty) {
if (self[p].isDirty()) return true;
}
else if (self[p].subscribe && self[p].push) { // assuming ko.observableArray
for (var i = 0, j = self[p]().length; i < j; i++) {
if (self[p]()[i].isDirty) {
if (self[p]()[i].isDirty()) return true;
}
}
}
}
return false;
}, this, { deferEvaluation: true });
}
Uwaga: Po prostu zauważyłem, że ten kod nie powiedzie się, jeśli mam inną nieruchomość komputerowej, która w zależności od isDirty. To było trochę oczekiwane, ale także niefortunne. Byłoby wspaniale, gdyby zamiast tego mogłem opóźnić i wymusić wszystkie subskrypcje po utworzeniu obiektu.
Skończyło się na użyciu metody endInit wywoływanej na końcu każdej konstrukcji klasy. Musiałem również podać jawną nazwę klasy, która wywołuje endInit, tak że tylko klasa "najwyżej" łańcucha dziedziczenia faktycznie wykonuje endInit. To nie jest idealne, ale działa. –