5

我在我的代码中使用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">&times;</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());

提前感谢你的帮助!

4

4 回答 4

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>
于 2014-01-06T10:56:21.777 回答
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]);
        }
    }
}
于 2013-08-02T00:05:33.937 回答
1

我写了一个简单的小提琴。它是带有 de 标签列表的构造组件。 小提琴

但这不是双向绑定。如果您不想这样做,我建议您创建一个自定义活页夹,在其中调用淘汰赛的 foreach 模型活页夹。 请参阅自定义模型绑定器的信息

在 init 函数上,您需要订阅淘汰 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);
    }
}

我希望这对你有帮助。

于 2012-10-12T10:32:06.790 回答
0

感谢 Cedric 无需编写自定义活页夹

我用这种方式解决链接

$("#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; }));
                }});
于 2012-10-31T11:06:26.887 回答