我在代码中使用http://aehlke.github.com/tag-it/ 如何与viewmodel绑定
html
<ul data-bind='jqueryui: "tagit",foreach: Tags' >
<li class="tagit-choice ui-widget-content ui-state-default ui-corner-all" data-bind='with: $data'>
<span class="tagit-label" data-bind='text: $data'></span>
<a class="tagit-close">
<span class="text-icon">×</span>
<span class="ui-icon ui-icon-close"></span>
</a>
<input type="hidden" name="item[tags][]" data-bind='value: $data' style="display: none;">
</li>
</ul>
Js代码
function AppViewModel() {
var self = this;
function Tag(data) {
this.Name = data;
}
self.Tags = ko.observableArray([
new Tag('red'),
new Tag('blue'),
new Tag('green')
]);
}
// Activates knockout.js
ko.applyBindings(new AppViewModel());
预先感谢您的协助!
答案 0 :(得分:8)
这是基于罗伯特·瓦格纳答案的淘汰赛的另一个绑定处理程序,因为我觉得它不够动态:
ko.bindingHandlers.tagit = {
//https://github.com/aehlke/tag-it
init: function (element, valueAccessor, allBindingsAccessor) {
var bind = function () {
valueAccessor().tags($(element).tagit("assignedTags"));
};
var options = $.extend({
allowSpaces: false,
caseSensitive: false,
showAutocompleteOnFocus: true,
afterTagAdded: function(t,s) { bind(); },
afterTagRemoved: function(t,s) { bind(); },
placeholderText: "",
preprocessTag: function () { },
beforeTagAdded: function (evt, tag) {
if (tag.tagLabel.length == 0 || tag.tagLabel.toLowerCase() === options.placeholderText.toLowerCase()) {
return false;
}
return true;
}
}, valueAccessor().options || {});
var tags = valueAccessor()["autocomplete"];
if (tags)
$.extend(options, {
autocomplete: $.extend({ source: tags.source, delay: 0, minLength: 0 },tags)
});
$(element).tagit(options);
},
update: function (element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
var tags = value.tags();
$(element).tagit("removeAll");
for (var x = 0; x < tags.length; x++) {
$(element).tagit("createTag", tags[x]);
}
}
};
我的预处理和自动完成功能:
self.TagAutocompleter = function (d, ds) {
DataMethod.postData("tag/autocomplete", d, function (data) {
ds(ko.utils.arrayMap(data, function (t) { return t.Tag; }));
});
};
self.TagProcessor = function (tag) {
return tag.toLowerCase().replace("#", '');
};
并在html中使用:
<ul data-bind="tagit:{tags:Tags, autocomplete:{source:TagAutocompleter, delay:250, minLength: 2}, options:{preprocessTag: TagProcessor}}">
</ul>
答案 1 :(得分:4)
这是一个自定义绑定https://gist.github.com/droyad/6136446
ko.bindingHandlers.tags = {
init: function (element, valueAccessor, allBindingsAccessor) {
var bind = function() {
var observable = valueAccessor();
observable($(element).tagit("assignedTags").join(','));
};
var options = {
allowSpaces: true,
caseSensitive: false,
showAutocompleteOnFocus: true,
afterTagAdded: bind,
afterTagRemoved: bind
};
var tags = allBindingsAccessor()["tagsSource"];
if (tags)
$.extend(options, {
autocomplete: { source: tags, delay: 0, minLength: 0 }
});
$(element).tagit(options);
$(element).data('uiTagit').tagInput.css("width", "50px");
},
update: function (element, valueAccessor) {
var value = ko.utils.unwrapObservable(valueAccessor());
var tags = value.split(',');
$(element).tagit("removeAll");
for (var x = 0; x < tags.length; x++) {
$(element).tagit("createTag", tags[x]);
}
}
}
答案 2 :(得分:1)
我写了一个简单的小提琴,它的工作原理。它是带有de tag列表的构造组件。 Fiddle
但这并不是两种方式的约束。 如果你不想那样做,我建议你创建一个自定义活页夹,它可以调用淘汰赛的foreach模型活页夹。 See information to Custom model binders
在init函数中,您需要subcibe来标记knockout observableArray中的更改以更新控件。您需要订阅onTagAdded事件和onTagRemoved事件。
有一个示例代码,我扩展了foreach组件:
ko.bindingHandlers.extendForeach = {
makeForeachValueAccessor: function (valueAccessor) {
return function () {
if ((!bindingValue) || typeof bindingValue.length == "number"){
bindingValue = {
data : bindingValue
}
}
return {
'data': bindingValue['data'],
'afterAdd': bindingValue['afterAdd'],
'beforeRemove': bindingValue['beforeRemove'],
'afterRender': bindingValue['afterRender'],
};
};
},
init: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var newValAccess = ko.bindingHandlers.extendForeach.makeForeachValueAccessor(valueAccessor);
return ko.bindingHandlers.foreach.init(element, newValAccess, allBindingsAccessor, viewModel, bindingContext);
},
update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
var newValAccess = ko.bindingHandlers.extendForeach.makeForeachValueAccessor(valueAccessor);
return ko.bindingHandlers.foreach.update(element, newValAccess, allBindingsAccessor, viewModel, bindingContext);
}
}
我希望这对你有所帮助。
答案 3 :(得分:0)
感谢Cedric无需编写自定义绑定器
我这样解决link
$("#mytags").tagit({
availableTags: JSON.parse(ko.toJSON(_.pluck(AppViewModel.Tags, 'Name'))),
onTagAdded: function (event, tagval) {
//on every add add with id if tag exist in system
var newtag = $(tagval).children('span.tagit-label').html();
var temp = _.find(AppViewModel.Tags, function (item) { return item.Name() == newtag; });
if (temp) {
AppViewModel().SelectedTags.push( Tag({ 'Id': temp.Id(), "Name": newtag} ));
}
else {
AppViewModel().SelectedTags.push( Tag({ "Name": newtag} ));
}
},
onTagRemoved: function (event, tagval) {
// do something special
var tempTag = $(tagval).children('span.tagit-label').html();
AppViewModel().SelectedTags.remove(_.find(SelectedTags(), function (item) { return item.Name == tempTag; }));
}});