Как создать составное свойство и использовать его в шаблоне jQuery? - PullRequest
1 голос
/ 06 сентября 2011

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

Вот что я пытаюсь сделать:

function Person(firstName, lastName)
{
    this.FirstName = firstName;
    this.LastName  = lastName;

    this.FullName = function ()
    {
        return this.FirstName + " " + this.LastName;
    }
}

Я хочу использовать FullName - шаблон jquery, но мне не повезло.

<script type="text/x-jquery-tmpl" id="tmplImg">
    {{each people}}
        <li>
            ${FullName}
        </li>
    {{/each}}
</script>

Я думаю, что это можно сделать каким-то образом, потому что библиотека knockout.js может выполнить это каким-либо образом, как показано в этом руководстве (шаг 4).

http://learn.knockoutjs.com/#/?tutorial=templates

Ответы [ 4 ]

2 голосов
/ 06 сентября 2011

Рабочая демонстрация :

function Person(firstName, lastName) {
    this.FirstName = firstName;
    this.LastName = lastName;
    var self = this;
    this.FullName = function() {
        return self.FirstName + ' ' + self.LastName;
    }
}
0 голосов
/ 06 сентября 2011

Ответ IAbstractDownvoteFactory - солидный ответ, и он определенно заслуживает одобрения, но я просто хочу представить один уровень абстракции помимо его / ее ответа:

Рассмотрим следующий помощник:

function createBoundMethodsFor(obj) {
    var proto = obj.constructor.prototype
    for(var method in proto)
        if(typeof(proto[method]) === 'function')
            obj[method] = function() { return proto[method].apply(obj, arguments); }
}

Тогда давайте снова посмотрим на конструктор для человека:

function Person(firstName, lastName) {
    this.FirstName = firstName;
    this.LastName = lastName;

    createBoundMethodsFor(this)
}

Person.prototype.FullName = function() {
    return this.FirstName + ' ' + this.LastName;
}

Этот помощник перебирает все functions в prototype объекта и создает связанные замыкания для каждого и переопределяет их как методы экземпляра, но они просто передают метод прототипа. Использование такого помощника может значительно упростить вашу жизнь, поскольку число методов объекта становится нетривиальным.

Но учтите, что связанные методы, подобные этому, приводят к интересным результатам, которых вы, возможно, не ожидаете, например:

var john = new Person("John", "Doe")
var jane = new Person("Jane", "Doe")
var bound = john.FullName

bound() // John Doe
bound.call(jane) // John Doe   (Not Jane like you might expect)

var unbound = john.constructor.prototype.FullName;
unbound() // null
unbound.call(john) // John Doe
unbound.call(jane) // Jane Doe

Скрипка здесь

0 голосов
/ 06 сентября 2011

Я ни в коем случае не эксперт по шаблонам jQuery, но это работает в моих тестах:

<script id="myTemplate" type="text/x-jquery-tmpl"> 
    ${$data.getFullName()}
</script>

function Person(firstName, lastName) {
    this.firstName = firstName;
    this.lastName = lastName;
}

Person.prototype.getFullName = function() {
    return this.firstName + " " + this.lastName;
};

var person = new Person("John", "Doe");

$("#myTemplate").tmpl(person).appendTo("#myOutput");
0 голосов
/ 06 сентября 2011

Используя ваш скрипт, я смог вызвать FullName и получить полное имя:

var pers = new Person("first", "last");
alert(pers.FullName());

Это то, что вы пытались достичь?

...