Я изучаю KO и пытаюсь создать простой элемент списка add/remove. но у меня есть следующие вопросы.binding и ko.toJSON не работает как ожидалось
Q1: Если вы нажмете «Добавить» без ввода имени, элемент, который вы только что добавите, будет иметь имя result
. почему и как предотвратить его, пока пустые, как действительные входы?
Q2: Я хотел бы использовать тег <pre>
, чтобы показать JSON модели текущего вида, но это ничего не показывает. Но кнопка показывает что-то. Я понял это. Мне нужно использовать ko.toJSON($data, null, 4)
.
Q3: Это связано с Q2, кнопка показывает что-то, но то, что оно показывает, кажется странным. После ввода нескольких элементов нажмите кнопку debug
. Вы увидите, что все элементы в модели просмотра заменены на последний элемент, который вы изменили.
Вот fiddle.
CSS:
input[type=text], select {
width:100px;
}
JS:
function foodie() {
this.name;
this.food;
}
function foodieApp() {
var self = this;
self.foodies = ko.observableArray();
self.foodieToAdd = ko.observable(new foodie());
self.addFoodie = function() {
this.foodies.push(this.foodieToAdd());
};
self.delFoodie = function (foodieToDel) {
self.foodies.remove(foodieToDel);
};
self.debug = function() {
alert(ko.toJSON(self, null, 4));
};
}
var app = new foodieApp();
ko.applyBindings(app);
HTML:
<table>
<thead>
<tr>
<td>Foodie's Name
<br/>
<input type=text data-bind='value: foodieToAdd().name' />
</td>
<td>Foodie's Food
<br/>
<select data-bind='value: foodieToAdd().food'>
<option value=apple>Apple</option>
<option value=banana>Banana</option>
<option value=cherry>Cherry</option>
</select>
</td>
<td>
<input type=button value=Add data-bind='click: addFoodie' />
</td>
</tr>
</thead>
<tbody data-bind='foreach: foodies'>
<tr>
<td>
<input type=text data-bind='value: name' />
</td>
<td>
<select data-bind='value: food'>
<option value=apple data-bind>Apple</option>
<option value=banana>Banana</option>
<option value=cherry>Cherry</option>
</select>
</td>
<td>
<input type=button value=del data-bind='click: $parent.delFoodie' />
</td>
</tr>
</tbody>
</table>
<input type=button value=debug data-bind='click: debug' />
<!-- why the following <pre> tag is empty? -->
<pre data-bind='text: ko.toJSON(app, null, 4)'></pre>
Это все правильно, но я не могу понять, почему 'result' становится помещен в' name' переплета. Есть идеи? –
Я не совсем понимаю, почему, кроме того, что он связан со связыванием со свойствами, не инициализируется. Это похоже на что-то в DOM-рендеринге логики Knockout. Если вы посмотрите на эту скрипку (http://jsfiddle.net/jearles/TgD6a/4/), вы увидите рендеринг отладки. Вы не увидите имени в своем объекте, но вы можете изменить 'result' на' res', и если вы нажмете add, оно примет это значение. –
Я сделал некоторую отладку этим утром, перейдя в отладочную версию нокаута. Причина «результата» набирается на самом деле довольно просто, но она включает в себя малоиспользуемый оператор JavaScript: 'with'. Нокаут оценивает эту функцию: 'с ($ контекста) {с ($ данных || {}) {возврата { 'значение': имя, ...}}}' Параметр 'with' заявления добавить '$ context' и' data' в цепочку областей, где будет пытаться решить 'name'. Ни у одного из них нет свойства 'name', но' this' (который есть Window) делает ... и это 'result'. Попробуйте изменить 'name' на' foodieName', и у нас больше нет неожиданного «результата». –