W nokaut js widzę Wyświetl modele zadeklarowane jako:
var viewModel = {
firstname: ko.observable("Bob")
};
ko.applyBindings(viewModel );
lub:
var viewModel = function() {
this.firstname= ko.observable("Bob");
};
ko.applyBindings(new viewModel ());
Jaka jest różnica między nimi, jeśli w ogóle?
Znalazłem tę dyskusję w grupie google knockoutjs, ale tak naprawdę nie dała mi satysfakcjonującej odpowiedzi.
Widzę powód, dla którego chciałbym zainicjować model przy użyciu niektórych danych, na przykład:
var viewModel = function(person) {
this.firstname= ko.observable(person.firstname);
};
var person = ... ;
ko.applyBindings(new viewModel(person));
Ale jeśli tego nie robię, to nie ma znaczenia, jaki styl wybiorę?
prototype
(metody, które często, na przykład, pobierają dane z serwera i odpowiednio aktualizują model widoku). Jednak nadal możesz oczywiście zadeklarować je jako właściwość literału obiektu, więc tak naprawdę nie widzę różnicy.Odpowiedzi:
Istnieje kilka zalet używania funkcji do definiowania modelu widoku.
Główną zaletą jest to, że masz natychmiastowy dostęp do wartości
this
równej tworzonej instancji. Oznacza to, że możesz:Zatem obliczona obserwowalna może zostać powiązana z odpowiednią wartością
this
, nawet jeśli zostanie wywołana z innego zakresu.Z literałem obiektu musiałbyś zrobić:
W takim przypadku można użyć
viewModel
bezpośrednio w obliczonym obserwowalnym, ale jest on oceniany natychmiast (domyślnie), więc nie można go zdefiniować w obrębie literału obiektu, ponieważviewModel
nie jest definiowany, dopóki literał obiektu nie zostanie zamknięty. Wiele osób nie lubi, że tworzenie modelu widoku nie jest zawarte w jednym wywołaniu.Innym wzorcem, którego można użyć w celu zapewnienia, że
this
zawsze jest odpowiedni, jest ustawienie zmiennej w funkcji równej odpowiedniej wartościthis
i użycie jej zamiast tego. To byłoby jak:Teraz, jeśli jesteś w zakresie pojedynczego elementu i wywołania
$root.removeItem
, wartośćthis
będzie w rzeczywistości danymi powiązanymi na tym poziomie (który byłby przedmiotem). Używając self w tym przypadku, możesz upewnić się, że jest ona usuwana z ogólnego modelu widoku.Inną opcją jest używanie
bind
, które jest obsługiwane przez nowoczesne przeglądarki i dodawane przez KO, jeśli nie jest obsługiwane. W takim przypadku wyglądałoby to tak:Jest wiele więcej do powiedzenia na ten temat i wiele wzorców, które można zbadać (np. Wzorzec modułu i ujawnianie wzorca modułu), ale w zasadzie użycie funkcji daje większą elastyczność i kontrolę nad sposobem tworzenia obiektu oraz możliwością odniesienia zmienne, które są prywatne dla instancji.
źródło
self
ithis
są takie same, więc oba będą równoważne. W funkcji removeItemself
staje się bardziej użyteczna, ponieważthis
nie byłaby już bieżącą instancją, gdy zostanie wykonana w kontekście elementu potomnego.Używam innej metody, choć podobnej:
Kilka powodów:
this
, które może wprowadzać w błąd, gdy jest używane wko.computed
s itpnew viewModel()
)źródło
My viewModel is a singleton, I don't need to create multiple instances (i.e. new viewModel())
ale nie jest jasne, co próbujesz powiedzieć, czyI don't need to create multiple instances
możesz użyć więcej, aby zrozumieć zaletę twojego podejścia. dziękifunction
to, że wykonasz go więcej niż raz. Jednak w moim przykładzie jest to anonimowa funkcja natychmiast wywołana, więc nie zostanie utworzona więcej niż raz. Jest bardzo podobny do Object Literal w powyższym przykładzie, ale daje więcej izolacji