2014-10-29 5 views
3

У меня возникли проблемы с привязкой foreach к списку функций. Я хочу, чтобы внутренний контекст был самой функцией, но вместо этого контекст связан с результатом вызова функции. Вот простой пример, который иллюстрирует это: (JSFiddle)Нокаут foreach со списком функций

JS:

ko.applyBindings({ 
    list: [ 
     function() { 
      return "hodor"; 
     } 
    ] 
}); 

HTML:

<!-- ko foreach: list --> 
<span data-bind="text: typeof $data"></span> 
<span data-bind="text: $data"></span> 
<br /> 
<!-- /ko --> 

Выход: "строка Foo", но я хотел бы, чтобы это было «функция функция() {return "foo";} "

В качестве обходного решения я могу сделать $parent.list[$index()], но это действительно уродливо, и я хотел бы избежать этого синтаксиса, если это возможно.

(Для объяснения в моем реальном использовании, они не являются простыми функциями, а функции, которые я присоединенные дополнительные свойства, которые я хочу сослаться, но я не могу ссылаться на них, потому что нокаут их вызов)

EDIT:

Похоже, что здесь есть проблема с версией KO. До 3.0 это не было проблемой, контекст всегда привязывался к функции не к значению. В 3.0, используя $rawData, вы получите функцию, а не это значение, но на 3.2 это не так, и я пытаюсь ее использовать.

Я обновил выше скрипку использовать 3.2, а вот скрипку для каждой версии, в том числе $rawData (за исключением 2.3, где $ RAWDATA не существует)

Knockout 2.3 fiddle: $rawData не нужен

Knockout 3.0 fiddle: $rawData

Knockout 3.2 fiddle: $rawData не работает.

Это может быть ошибка KO 3.2?

+0

Я уверен, что это какое-то смешение с тем, как предполагается, что функция будет наблюдаемой и поэтому вызывает ее. Одна из возможных работ может заключаться в том, чтобы просто обернуть ваши функции в другую функцию следующим образом: http://jsfiddle.net/dq4ec706/3/, но это кажется действительно, действительно глупым. Он делает работу '$ data' как на 3.0, так и на 3.2, но не на 2.3. –

+0

Да, я бы предпочел использовать '$ parent.list [$ index()]' обходной путь, который всегда срабатывает, а не переносить мои функции снова, лично. – Retsam

ответ

2

Нет, это была ошибка в KO 3.0.

В < 2.3 это была недостающая особенность. Потому что без $rawData вы не смогли работать с массивами, содержащими наблюдаемый [ko.observable(1), ko.observable(2)].

В 3.0 $rawData был введен, но это было ошибкой. Который был зафиксирован в 3.1 https://github.com/knockout/knockout/pull/1206.

Так что это правильное поведение подытоженных daedalus28 в вышеприведенном связанный вопросе:

$rawData должен быть возвращаемым значением, если это функция, но не наблюдается. Если это наблюдаемое (или результат функции является наблюдаемым), она должна быть развернута в $data и не $rawData - $rawData должны сохранить фактический наблюдаемый (результат функции)

Так в настоящее время использование вами дело не поддерживается KO.

Таким образом, вы должны использовать на $parent.list[$index()] или не ставить свои функции прямо в массив.

Оберните их наблюдаемые

list: [ 
     ko.observable(function() { 
      return "foo"; 
     }), 
     ko.observable(function() { 
      return "bar"; 
     }), 
     ko.observable(function() { 
      return "hodor"; 
     }) 
    ] 

Demo JSFiddle.

или положить их на несколько фиктивных объектов:

list: [ 
    {bar: function() { 
     return "foo"; 
    }}, 
    {bar: function() { 
     return "bar"; 
    }}, 
    {bar: function() { 
     return "hodor"; 
    }} 
] 

А Вы пишете:

<span data-bind="text: bar"></span> 

Demo JSFiddle.

+0

Я не уверен, что я следую их логике, почему функции всегда должны быть развернуты для меня, в то время как наблюдаемые - нет; но я полагаю, что смогу ответить на вопрос, который вы опубликовали, если захочу. Спасибо за ответ! – Retsam