【问题标题】:How to use tagit with knockout如何在淘汰赛中使用 tagit
【发布时间】:2012-10-03 00:55:09
【问题描述】:

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

提前感谢您的帮助!

【问题讨论】:

    标签: knockout.js knockout-mapping-plugin tag-it


    【解决方案1】:

    这是基于 Robert Wagner 的回答的另一个用于淘汰赛的绑定处理程序,因为我觉得它不够动态:

    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>
    

    【讨论】:

    • 我也修复了更新部分的错误,因此它可以使用从一开始就在可观察对象中的数据
    • 能否为 TagAutocompleter 和 TagProcessor 包含一个代码 sn-p?
    • 我已经用那些+小更新更新了原始答案:)
    【解决方案2】:

    这是一个自定义绑定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]);
            }
        }
    }
    

    【讨论】:

      【解决方案3】:

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

      但这不是双向绑定。 如果您不想这样做,我建议您创建一个自定义活页夹,在其中调用淘汰赛的 foreach 模型活页夹。 See information to Custom model binders

      在init函数上,你需要订阅knout observableArray中的tags变化来更新控件。并且需要订阅 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);
          }
      }
      

      希望对你有所帮助。

      【讨论】:

        【解决方案4】:

        感谢 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; }));
                        }});
        

        【讨论】:

          猜你喜欢
          • 2017-02-15
          • 2015-02-01
          • 1970-01-01
          • 2012-11-13
          • 2015-06-11
          • 1970-01-01
          • 2013-09-13
          • 1970-01-01
          • 2013-04-10
          相关资源
          最近更新 更多