2015-04-19 5 views
0

Я пытаюсь реализовать пользовательскую привязку для макета аккордеонного документа на веб-странице, но я столкнулся с проблемой, которую я не могу легко решить.Knockout.js не удалось обработать привязку: undefined не является функцией?

Сразу после загрузки страницы, я представил с ошибкой:

Uncaught TypeError: Unable to process binding "accordion: function(){return currentAccordionSection }" 
Message: undefined is not a function 

Я попытался объявить мой наблюдаемым и как функции и обычно в data-bind синтаксиса без успеха. Я инициализировал свой наблюдаемый со значением по умолчанию (null), и он не исправил эту проблему. Ниже вся моя ViewModel:

var libraryViewModel = function() { 
var self = this; 

ko.bindingHandlers.accordion = { 
    update: function (element, valueAccessor) { 
     console.log(ko.unwrap(valueAccessor())); 
     var value = ko.unwrap(valueAccessor()); 
     var section = $(element.text()); 

     //ko.bindingHandlers.css.update(element, function() { 
     // if (value === section) { 
     //  return 'library-section-active'; 
     // } 
     //}); 

     //ko.bindingHandlers.css.update($(element).children('i:last-child').get(0), function() { 
     // if (value === section) { 
     //  return 'fa fa-chevron-up'; 
     // } else { 
     //  return 'fa fa-chevron-down'; 
     // } 
     //}); 
    } 
} 

self.currentAccordionSection = ko.observable(null); 
self.updateAccordionSection = function (section) { 
    self.currentAccordionSection(section); 
} 

} 

Некоторые из приведенной выше коды закомментированы, как это не имеет отношения к проблеме под руку, и я отключил его реализовать пониженный тестовый пример, чтобы сузить проблему. Вот моя обязательная декларация:

<h2 class="library-header" data-bind="accordion: currentAccordionSection, click: updateAccordionSection.bind('Text')"> 

Что именно я делаю неправильно?

+0

Несколько вопросов. Почему ваша функция 'bindingHandler' * внутри * является конструктором представлений? Обычно вы указываете свои привязки больше к началу/в начале. Кроме того, совсем немного вашего кода было прокомментировано, почему? Наконец, у вас есть 'element.text()' в коде обработчика привязки, но я не уверен, как это работает, поскольку '.text()' - это только метод для объектов jQuery, а не для HtmlElements, которые передаются функции привязки обработчика ... (PS. Если я исправить/закрыть все эти проблемы, [ваш код не будет воспроизводить ошибку] ​​(http://jsfiddle.net/etaj369c/).) – Jeroen

+0

Для первого вопроса, я не уверен. Так я всегда это делал. Если это неверно, я переведу его в другое место. Где будет лучшее место? 2) Потому что это не относится к вопросу, но я хотел включить его в любом случае, поэтому я не получаю ответы типа «пожалуйста, напишите весь свой код». 3) Я использую jQuery в качестве помощника. – ReactingToAngularVues

+0

Это нормально, чтобы добавить какой-то дополнительный код, просто вы ничего не объяснили * почему * он закомментирован или как это уместно. Во всяком случае, было бы полезно иметь Stack Snippet c.q. достаточно кода для фактического воспроизведения вашего сценария. Как вы можете видеть из моей скрипки, я делаю * не * ошибку, которую вы получаете с отправленным кодом. – Jeroen

ответ

2

Проблема эта линия:

var section = $(element.text()); 

согласно knockout's documentation

element — The DOM element involved in this binding

text функция JQuery не DOM функции, так что я думаю, что вы ищете что-то вроде:

$(element).text() или $($(element).text()) вместо этого? Я бы предположил, что первый из них имеет смысл. Что касается вложенного обработчика привязки, я не уверен, почему это находится в viewmodel, так как он отображается на глобальном объекте нокаута, который вы не защищаете от чего-либо, что делает ваш код более нечитаемым. Они предназначены для восстановления, поэтому вы можете использовать их с разными viewModels

+0

Eugh, мой редактор кода размял мои скобки и даже не предупредил меня об ошибке синтаксиса! Благодарю. Где я должен размещать свои привязывающие обработчики, в любом случае? – ReactingToAngularVues

+2

Разный файл, глобальный охват, идея в том, что они повторно используются, поэтому другие модели представлений могут использовать их не только в вашей библиотекеViewModel. – dbarnes

+0

Хорошо, спасибо. Затем будут сделаны некоторые структурные изменения. – ReactingToAngularVues

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