2013-05-15 5 views
19

В последнее время я использую Knockout.js для большого количества проектов, и я пишу много повторяющегося кода. Я хотел бы иметь возможность определить класс BaseViewModel и унаследовать от него мои ViewModels, специфичные для этой страницы. Я немного смущен о том, как это сделать - Javascript. Вот мой основной BaseViewModel:Нокаут ViewModel базовый класс, наследование Javascript

(function (ko, undefined) { 
    ko.BaseViewModel = function() { 
     var self = this; 
     self.items = ko.observable([]); 
     self.newItem = {}; 
     self.dirtyItems = ko.computed(function() { 
      return self.items().filter(function (item) { 
       return item.dirtyFlag.isDirty(); 
      }); 
     }); 
     self.isDirty = ko.computed(function() { 
      return self.dirtyItems().length > 0; 
     }); 
     self.load = function() { } 
    }; 
}(ko)); 

Я хотел бы иметь возможность перечислить подписи методов, как load в BaseViewModel, а затем дать им определение в наследуемых ViewModel. Возможно ли это? Я нашел несколько решений в Интернете, но все они полагаются на определение функций/классов, чтобы заставить наследование работать.

+0

Почему вы передаете 'undefined' в функцию? – Tyrsius

+0

http://programmers.stackexchange.com/a/158376/90240 – gwely

+0

Да, никогда не видел этого раньше. Я также никогда не сталкивался с тем случаем, когда это не вызывает ошибок, и он не объясняет, что это такое. – Tyrsius

ответ

17

С вашего BaseViewModel только добавляет все свойства/методы для this (а не с помощью прототипа), то это довольно легко:

В своих новых моделях просмотра, просто позвоните BaseViewModel:

var MyVM = function() { 
    var self = this; 
    ko.BaseViewModel.call(self); 

    self.somethingElse = ko.observable(); 
    self.itemCount = ko.computed(function() { return self.items().length; }); 
    self.items([1, 2, 3]); 
}; 


// ... 
var vm = new MyVM(); 
+0

Ну, это проще, чем я ожидал. Теперь мне просто нужно выяснить, как это работает! – gwely

+0

Строка 'ko.BaseViewModel.call (self)' такая же, как и ': base()' в C#, правильно? – gwely

+1

@theyshookhands Да, это то же самое, что и вызов ': base()'. «ViewModel.prototype = new BaseViewModel()' такой же, как «Class: SubClass» в C#. – Tyrsius

10

Наследование Javascript выполняется двумя частями. Первый - в конструкторе, а второй - на прототипе (который вы не используете, поэтому можете пропустить).

var ViewModel = function(data) { 
    BaseViewModel.call(this); 
}; 
//you only need to do this if you are adding prototype properties 
ViewModel.prototype = new BaseViewModel(); 

К последней точке, о переопределении load, ни его другим, что поставив load функцию на вашем ViewModel нормально. Javascript позволяет вам переопределить любые свойства объектов с помощью чего-либо, особых шагов здесь нет.

Это fiddle demonstrating наследство.

+0

Если вам нужно только беспокоиться о поддержке современных браузеров, вы можете заменить эту последнюю строку «Viewmodel.prototype = Object.create (BaseViewModel.prototype);» и избежать некоторых сложных проблем с любыми нежелательными эффектами вызова «BaseViewModel» в этом путь. – Brandon

+0

И легко прошить 'Object.create' в старых браузерах:' var objCreate = Object.create || функция (o) {функция F() {}; F.prototype = o; вернуть новый F(); }; ' –

Смежные вопросы