Я хочу применить предопределенные состояния к флажкам с помощью Knockout.js Я уже пробовал десятки вещей, но не могу заставить это работать.
Это мой код:
function DemoItem(id, name, state) {
var self = this;
self.id = ko.observable(id);
self.Name = ko.observable(name);
self.Selected = ko.observable(state);
}
function ViewModel() {
var self = this;
self.availableItems = ko.observableArray([]);
self.init = function() {
self.availableItems.push(new DemoItem(1, 'One', true));
self.availableItems.push(new DemoItem(2, 'Two', true));
self.availableItems.push(new DemoItem(3, 'Three', false));
self.availableItems.push(new DemoItem(4, 'Four', true));
self.availableItems.push(new DemoItem(5, 'Five', true));
};
self.relayState = ko.computed({
read: function() {
ko.utils.arrayForEach(self.availableItems, function(item) {
return item.Selected();
});
},
write: function(value) {
if (value) {
console.info("associate item ");
} else {
console.info("disasociate item ");
}
}
})
}
var viewModel = new ViewModel();
ko.applyBindings(viewModel);
viewModel.init();Available Items:
<div data-bind = "foreach: $root.availableItems">
<input type = "checkbox" data-bind = "value: id(), checked: $root.relayState" />
<span data-bind = "text: ' ' + Name()"></span>
<br/>
</div>Я не могу установить флажки для первоначального применения предопределенных значений.
Это ссылка на JSfiddle: http://jsfiddle.net/w392rpxf/
Извините, забыл упомянуть, что мне нужно также иметь возможность управлять отдельными флажками, отправляя переключаемый флажок в функцию, которая затем привязывает его к отмеченному или неотмеченному состоянию. Итак, в основном я сначала хочу установить или снять флажки в зависимости от предопределенного состояния, а затем вручную управлять ими и передавать их состояние в функцию.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я не совсем уверен, что вы хотите сделать, но похоже, что обычные привязки нокаута должны вас защитить.
Вы можете создать observableArray, который содержит выбор. (Не)установка любого флажка автоматически добавляет или удаляет элемент в/из этого массива.
Свойство Selected вашего DemoItem используется только для заполнения его начального состояния в функции инициализации.
function DemoItem(id, name, state) {
var self = this;
self.id = ko.observable(id);
self.Name = ko.observable(name);
self.Selected = ko.observable(state);
}
function ViewModel() {
var self = this;
self.availableItems = ko.observableArray([]);
self.selectedItems = ko.observableArray([]);
// Log changes to the console
self.selectedItems.subscribe(function(sel) {
console.info("Selected are: " + sel.map(function(s) {
return s.Name();
}).join(", "));
});
self.init = function() {
self.availableItems([
new DemoItem(1, 'One', true),
new DemoItem(2, 'Two', true),
new DemoItem(3, 'Three', false),
new DemoItem(4, 'Four', true),
new DemoItem(5, 'Five', true)
]);
// Set up the initial state
self.selectedItems(
self.availableItems()
.filter(function(item) {
return item.Selected();
})
);
};
}
var viewModel = new ViewModel();
ko.applyBindings(viewModel);
viewModel.init();<script src = "https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
Available Items:
<div data-bind = "foreach: $root.availableItems">
<input type = "checkbox" data-bind = "checked: $root.selectedItems, checkedValue: $data" />
<span data-bind = "text: ' ' + Name()"></span>
<br/>
</div>Обновлено: поскольку вы хотите знать, какой из них изменился, вот еще один пример:
function DemoItem(id, name, state, onChange) {
var self = this;
self.id = ko.observable(id);
self.Name = ko.observable(name);
self.Selected = ko.observable(state);
self.Selected.subscribe(function(newValue) {
onChange(self, newValue);
});
}
function ViewModel() {
var self = this;
self.availableItems = ko.observableArray([]);
self.selectedItems = ko.pureComputed(function() {
return self.availableItems().filter(function(demoItem) {
return demoItem.Selected();
});
});
// Log changes to the console
self.selectedItems.subscribe(function(sel) {
console.info("Selected are: " + sel.map(function(s) {
return s.Name();
}).join(", "));
});
// Log the individual that caused the change
self.onItemChange = function(item, newValue) {
console.info("The item that changed was " + item.Name() + " (" + newValue + ")");
};
self.init = function() {
self.availableItems([
new DemoItem(1, 'One', true, self.onItemChange),
new DemoItem(2, 'Two', true, self.onItemChange),
new DemoItem(3, 'Three', false, self.onItemChange),
new DemoItem(4, 'Four', true, self.onItemChange),
new DemoItem(5, 'Five', true, self.onItemChange)
]);
};
}
var viewModel = new ViewModel();
ko.applyBindings(viewModel);
viewModel.init();<script src = "https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
Available Items:
<div data-bind = "foreach: $root.availableItems">
<input type = "checkbox" data-bind = "checked: Selected" />
<span data-bind = "text: ' ' + Name()"></span>
<br/>
</div>Извините за неясность, надеюсь, теперь я могу объяснить, что я хочу сделать. Я хочу установить начальные состояния, используя чтение relayState. После этого я хочу знать точный флажок, который установлен или снят, а затем зарегистрируйте это с помощью console.info() в relayState write
Я включил еще один пример, который делает именно то, что вы описываете. Опять же, я не думаю, что вам нужен компьютер с возможностью записи.
это можно сделать с записываемыми вычисленными? Если да, то как? Спасибо за ваши ответы до сих пор
Возможно, но не вижу смысла пробовать. Ваш вопрос касается решения проблемы или вы просто пытаетесь узнать больше о записываемых вычислениях? Потому что я думаю, что это не правильный вариант использования для них.
Спасибо что подметил это. Не могли бы вы объяснить, каков правильный вариант использования записываемых вычислений?
Также еще один вопрос. Как я могу контролировать, будут ли флажки инициализированы с их начальным значением в непроверенном состоянии с другой логической переменной? Как это сделать?
Вычисляемые с возможностью записи чаще всего используются, когда вы хотите, чтобы значения, которые вы хранить, немного отличались от значений, которые вы ввод, вывод. Например: пользователь вводит "100" в поле ввода, я хочу сохранить это как 100 и отобразить как $100.00.
Вы уже передаете начальные проверенные состояния конструктору DemoItem. Если вы хотите, чтобы они были инициализированы по-разному, вы должны передать им другое начальное значение.
Позвольте мне объяснить лучше, я хочу иметь новую защелку с логическим именем. Если защелка истинна, то применяется начальное состояние, если защелка ложна, применяются непроверенные состояния по умолчанию.
В init после создания предметов: if (!latch) self.availableItems().forEach(x => x.Selected(false))
Какова цель вашей вычисляемой функции relayState? Если вы обойдете это и привяжете свои флажки непосредственно к модели DemoItem с помощью «checked: Selected», предопределенные значения будут работать правильно.
relayStateэто проблема, но я не знаю, как это исправить, не зная, что она должна делать.