KnockoutJs: получить связанный элемент из экземпляра модели
Возможно ли получить соответствующий элемент (или элементы), к которому привязан экземпляр данных (модели)?
Например, у меня есть массив объектов объектов Person в свойстве ViewModel.
Я привязываю ViewModel к представлению, которое его отображает, например:
<div class="people" data-bind="template: { foreach: people }">
<a href="#" class="person" data-bind="text: name"></a>
</div>
Затем я связываю некоторые обработчики событий через jQuery:
$container.on('click', '.person', function(e){
e.preventDefault();
self.showPerson( ko.dataFor(this) );
});
В моем методе showPerson
я бы сохранил ссылку на модель. Я/мог/также сохранить ссылку на элемент, но я не хочу, если мне не нужно.
self.showPerson = function(person) {
// can i get the corresponding element from the 'person' model?
};
У кого-нибудь есть идеи?
Ответы
Ответ 1
Ваш синтаксис и использование $container с jquery и второй аргумент '.person' мне незнакомы, но в вашем обработчике кликов нет this
элемента, который был нажат? Не могли бы вы передать это и вашему методу showPerson?
$container.on('click', '.person', function(e){
e.preventDefault();
self.showPerson( ko.dataFor(this), this );
});
self.showPerson = function(person, element) {
// can i get the corresponding element from the 'person' model?
};
Я не знаю, как далеко от головы, чтобы получить элементы, к которым привязан наблюдаемый, но это может быть несколько разных элементов. У вас может быть текстовое поле для "имени", отображение имени в диапазоне, использование его в вычисленных, наличие подписчиков и использование имени(). Length в вычислении в другой привязке, например.
Тем не менее, если вы используете отладочную версию нокаута, вы можете видеть, что ваши наблюдаемые объекты имеют свойство _subscriptions
, которое может иметь то, что вы ищете. Минимизированная версия - это какой-то один символ, который я думаю.
Ответ 2
Вы можете просто создать настраиваемую привязку
// data-bind="element: observable"
// sets observable to element ..
ko.bindingHandlers.element = {
init: function(element, valueAccessor) {
var target = valueAccessor();
target(element);
}
};
В вашей модели просмотра создайте "поле" для хранения элемента:
person.el = ko.observable(null);
Затем в вашем html-шаблоне.
<div data-bind="element: el"> .... </div>
Ответ 3
Почему бы не переместить привязку события клика внутри вашего foreach
?
<a href="#" class="person" data-bind="text: name, click: showPerson"></a>
В этом случае ваша функция showPerson()
будет иметь правильные данные для person
ИЗМЕНИТЬ:
Извините, но, я думаю, я пропустил суть вашего вопроса:
self.showPerson = function (person, event) {
element = event.srcElement
...
}
Ответ 4
self.showPerson = function(data, event) {
// event.currentTarget is the DOM element
// $(event.currentTarget) gives the jQuery element
}
Ответ 5
Я считаю, что наилучшей практикой является привязка непосредственно к функции на модели представления, а не привязка обработчиков.
Щелкните привязку к родительской функции в foreach