【发布时间】:2013-11-01 17:59:39
【问题描述】:
我正在尝试为我的文本计数跟踪器创建一个剔除模板,以便我可以为我正在创建的页面上的每个文本区域重复此操作。 我创建了两个小提琴,展示了我一直在采用的不同方法: 1.http://jsfiddle.net/ajdisalvo/9W84x/3/ 和 2.http://jsfiddle.net/ajdisalvo/ex2uJ/
在这两者中,我都创建了一个绑定处理程序,它是我试图绑定到的模板的包装器。
在第一种方法中,我创建了一个单独的 viewModel,将其附加到现有的主 viewModel 上,它似乎会一直运行,直到它尝试更新主 viewModel 中的“成功”值。此时,它将值设置为 [Object object]。虽然,这个小提琴似乎真的很接近工作,但我担心我可能会创建一个递归循环,这可能是这种方法的固有缺陷。
(function (ko) {
ko.bindingHandlers.templateWrapper = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, context) {
var existingOptions = ko.utils.unwrapObservable(valueAccessor());
viewModel[existingOptions.itemName] = new subModel(existingOptions.dataInput(), existingOptions.maxLength);
viewModel[existingOptions.itemName].itemText.subscribe(function (value) {
existingOptions.dataInput(value);
});
newOptions = ko.bindingHandlers.templateWrapper.buildTemplateOptions(existingOptions, viewModel[existingOptions.itemName]);
//return ko.bindingHandlers.template.init(element, function () { return newOptions; }, allBindingsAccessor, viewModel, context);
return { controlsDescendantBindings: true };
},
'update': function (element, valueAccessor, allBindingsAccessor, viewModel, context) {
newOptions = ko.bindingHandlers.templateWrapper.buildTemplateOptions(valueAccessor(), viewModel[valueAccessor().itemName]);
ko.bindingHandlers.template.update(element, function () { return newOptions; }, allBindingsAccessor, viewModel, context);
},
//extend the existing options by adding a name
buildTemplateOptions: function (options, vm) {
return { data: vm, name: ko.bindingHandlers.templateWrapper.templateName };
},
templateName: "textTrackerTemplate"
};
var viewModel = {
successes: ko.observable("Test input")
};
var subModel = function (value, maxLength) {
var self = this;
self.itemText = ko.observable(value);
self.maxLength = ko.observable(maxLength);
self.currentLength = ko.observable(self.itemText().length);
self.remainingLength = ko.computed(function () { return self.maxLength() - self.currentLength() });
self.hasFocus = ko.observable(false);
self.updateRemaining = function (data, event) {
var e = $(event.target || event.srcElement);
self.currentLength(e.val().length);
if (self.currentLength() > self.maxLength()) {
e.val(e.val().substr(0, self.maxLength()));
self.ItemText(e.val());
self.currentLength(self.itemText().length);
}
};
};
ko.applyBindings(viewModel);
} (ko));
在我的第二种方法中,我在绑定处理程序中使用扩展器来添加必要的属性来填充我的计数跟踪器,但是在淘汰赛呈现页面时似乎没有实例化在扩展器中创建的对象。
(function (ko) {
ko.bindingHandlers.templateWrapper = {
init: function (element, valueAccessor, allBindingsAccessor, viewModel, context) {
var existingOptions = ko.utils.unwrapObservable(valueAccessor());
newOptions = ko.bindingHandlers.templateWrapper.buildTemplateOptions(existingOptions, valueAccessor);
return ko.bindingHandlers.template.init(element, function () { return newOptions; }, allBindingsAccessor, viewModel, context);
},
'update': function (element, valueAccessor, allBindingsAccessor, viewModel, context) {
var existingOptions = ko.utils.unwrapObservable(valueAccessor());
newOptions = ko.bindingHandlers.templateWrapper.buildTemplateOptions(existingOptions, valueAccessor);
ko.bindingHandlers.template.update(element, function () { return newOptions; }, allBindingsAccessor, viewModel, context);
},
buildTemplateOptions: function (options, valueAccessor) {
valueAccessor().dataInput = valueAccessor().dataInput.extend({ textTracker: options.maxLength });
return { data: valueAccessor, name: ko.bindingHandlers.templateWrapper.templateName };
},
templateName: "textTrackerTemplate"
};
var viewModel = {
successes: ko.observable("Test input")
};
ko.extenders.textTracker = function (target, maxLength) {
target.itemText = ko.computed({
read: function () {
return target();
},
write: function (value) {
target(value);
}
});
target.maxLength = ko.observable(maxLength);
target.currentLength = ko.observable(target.itemText().length);
target.remainingLength = ko.computed(function () {
return target.maxLength() - target.currentLength(); });
target.hasFocus = ko.observable(false);
target.updateRemaining = function (data, event) {
var e = $(event.target || event.srcElement);
target.currentLength(e.val().length);
if (target.currentLength() > target.maxLength()) {
e.val(e.val().substr(0, target.maxLength()));
target(e.val());
target.currentLength(target.itemText().length);
}
};
return target;
};
ko.applyBindings(viewModel);
} (ko));
提前感谢您提供的任何帮助/建议..
【问题讨论】:
标签: javascript knockout.js model-binding