2012-03-16 2 views
2

Я ищу через выбивные учебники, и все примеры создания модели представления, используя «новое» ключевое слово:Создание яваскрипта нокаута ViewModel без нового ключевого слова

//from learn.knockoutjs.com 
function AppViewModel() { 
    this.firstName = ko.observable("Bert"); 
    this.lastName = ko.observable("Bertington"); 
    this.fullName = ko.computed(function() { 
    return this.firstName() + " " + this.lastName();  
    }, this); 
} 
ko.applyBindings(new AppViewModel()); 

Я пытаюсь избегать использования новое ключевое слово, которое обычно работает отлично, но я нахожусь в затруднении, чтобы работать с полным вычислительным свойством. Это то, к чему я придумал.

function makeViewModel() { 
    return { 
    firstName: ko.observable("Bert"), 
    lastName: ko.observable("Bertington"), 
    fullName: ko.computed(function() { 
    return this.firstName() + " " + this.lastName();  
    }, this) }; 
} 
ko.applyBindings(makeViewModel()); 

... который, очевидно, терпит неудачу, поскольку «это» больше не относится к локальному объекту внутри функции, переданной для вычисления. Я мог бы обойти это, создав переменную и сохранил модель представления, прежде чем присоединять вычисляемую функцию и вернуть ее, но если существует более элегантное и компактное решение, которое не требует от меня проверки того, что методы, зависящие друг от друга, прикрепленный в правильном порядке, я бы хотел использовать это вместо этого.

Есть ли лучшее решение?

+0

Для меня самый важный вопрос: почему вы пытаетесь избежать нового ключевого слова? Как сказал Джон Папа, есть способы сделать объекты без новых, но почему?Это просто ваше предпочтение (вам не нравятся новые) или у вас есть определенные проблемы при его использовании? –

+0

Я стараюсь избегать нового ключевого слова, пока не выясню это: http://jsperf.com/ffs-constructors – Zaz

+0

@GeorgeMavritsakis: одна из причин, почему следует избегать «нового», - представить себе ущерб, который может быть причинен, если кто-то использует код забыл использовать 'new', например,' ko.applyBindings (AppViewModel()); 'Это добавит (или заменит значения' firstName', 'lastName' и т. д. в текущем контексте, возможно, окно браузера объект.Это может быть не слишком вредно.Но что, если конструктор включил строку, такую ​​как 'this.Date = ...'? Вдруг конструктор Date был переопределен. Это одна из веских причин. –

ответ

3

При создании в функции нет необходимости возвращать новый объект. Вместо этого вы бы сделали:

var ViewModel = function() { 
    this.firstName = ko.observable("Bert"); 
    this.lastName = ko.observable("Bertington"); 
    this.fullName = ko.computed(function() { 
     this.firstName() + " " + this.lastName(); 
    }, this); 
}; 

Теперь у вас есть доступ к соответствующему этому в вычисленном наблюдаемом.

Если вы действительно не хотите использовать «новый» (нет никаких причин, почему вы не должны в этом случае), то вы могли бы сделать что-то вроде:

var createViewModel = function() { 
    var result = { 
     firstName: ko.observable("Bert"), 
     lastName: ko.observable("Bertington") 
    }; 

    result.fullName = ko.computed(function() { 
     return result.firstName() + " " result.lastName(); 
    }); 

    return result; 
}; 
+0

как бы я назвал этот код без используя 'new'? – Zaz

+0

Вы бы использовали «новый» в этом случае, но ваше «это» было бы правильным в ваших вычисленных наблюдаемых. –

0

Вы можете исполнять новый, как так (взято из this great pattern resource)

function Waffle() { 
    if (!(this instanceof Waffle)) { 
    return new Waffle(); 
    } 

    this.tastes = "yummy"; 
} 

Однако я не уверен, что вы имеете в виду

Я стараюсь избегать использования -го e новое ключевое слово, которое обычно работает отлично, но я нахожу, что проблема в том, чтобы получить fullName, вычисленное , свойство работать. Это то, к чему я придумал.

Это должно хорошо работать, можете ли вы показать нам конкретный пример в jsfiddle, который не работает с использованием нового.

Надеюсь, это поможет.

5

Вы можете наверняка обойти новое ключевое слово, сделав функцию self invoking, но я думаю, что вам лучше решить проблему ключевого слова «this». Мне нравится показывать людям 3 способа создания viewmodels.

  1. литерал объекта http://jsfiddle.net/johnpapa/u9S93/
  2. как функция http://jsfiddle.net/johnpapa/zBqxy/
  3. с разоблачающий модуля Pattern http://jsfiddle.net/johnpapa/uRXPn/

При использовании вариант 2 или 3 выше, гораздо легче иметь дело с "это" ключевое слово.

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