Есть несколько преимуществ использования функции для определения модели представления.
Основным преимуществом является то, что у вас есть немедленный доступ к значению this
, равному создаваемому экземпляру. Это означает, что вы можете сделать:
var ViewModel = function(first, last) {
this.first = ko.observable(first);
this.last = ko.observable(last);
this.full = ko.computed(function() {
return this.first() + " " + this.last();
}, this);
};
Таким образом, ваша вычисляемая наблюдаемая может быть связана с соответствующим значением this
, даже если она вызывается из другой области видимости.
С литералом объекта вы должны сделать:
var viewModel = {
first: ko.observable("Bob"),
last: ko.observable("Smith"),
};
viewModel.full = ko.computed(function() {
return this.first() + " " + this.last();
}, viewModel);
В этом случае вы можете использовать viewModel
непосредственно в вычисляемой наблюдаемой, но она оценивается немедленно (по умолчанию), поэтому вы не можете определить ее в литерале объекта, как viewModel
это не определено до тех пор, пока литерал объекта не будет закрыт. Многим людям не нравится, что создание вашей модели представления не заключено в один вызов.
Другой шаблон, который вы можете использовать, чтобы убедиться, что this
он всегда уместен, - установить переменную в функции равной соответствующему значению this
и использовать ее вместо этого. Это было бы как:
var ViewModel = function() {
var self = this;
this.items = ko.observableArray();
this.removeItem = function(item) {
self.items.remove(item);
}
};
Теперь, если вы находитесь в области действия отдельного элемента и вызова $root.removeItem
, значение this
фактически будет привязывать данные на этом уровне (который будет элементом). Используя в этом случае self, вы можете убедиться, что он удаляется из общей модели представления.
Другой вариант использования bind
, который поддерживается современными браузерами и добавляется KO, если он не поддерживается. В этом случае это будет выглядеть так:
var ViewModel = function() {
this.items = ko.observableArray();
this.removeItem = function(item) {
this.items.remove(item);
}.bind(this);
};
По этой теме можно сказать гораздо больше и множество шаблонов, которые вы можете исследовать (например, шаблон модуля и раскрытие шаблона модуля), но в основном использование функции дает вам большую гибкость и контроль над тем, как создается объект, и возможность ссылаться на него. переменные, которые являются частными для экземпляра.
prototype
(методы, которые часто, например, выбирают данные с сервера и соответственно обновляют модель представления). Однако вы все равно можете объявить их как свойство литерала объекта, поэтому я не вижу разницы.