2012-10-12 11 views
5

używam http://aehlke.github.com/tag-it/ w moim kodu jak powiązać z ViewModelJak korzystać Znaczniki z nokautem

kod 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()); 

Z góry dzięki za pomoc!

Odpowiedz

0

dzięki Cedric ma potrzeby, aby napisać niestandardowy spoiwem

rozwiązać ten sposób 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; })); 
       }}); 
1

Piszę proste skrzypce tam, gdzie to działa. Jest to komponent konstrukcyjny z listą de tagów. Fiddle

Ale to nie jest dwojaki sposób wiązania. Jeśli nie chcesz tego zrobić, radzę stworzyć niestandardowy segregator, w którym nazywa się segregatorowy model foreach. See information to Custom model binders

W funkcji init należy zaakceptować zmiany znaczników w nokaut observableArray w celu zaktualizowania formantu. Musisz zasubskrybować zdarzenie onTagAdded i zdarzenie onTagRemoved.

Istnieje przykładowy kod gdzie mogę przedłużyć komponent 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); 
    } 
} 

mam nadzieję, że to pomoże.

4

Tutaj jest zwyczaj wiązania 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]); 
     } 
    } 
} 
8

Oto kolejna obsługi wiążące dla nokaut na podstawie Odpowiedź Roberta Wagnera, ponieważ nie sądziłem, że jest wystarczająco dynamiczny:

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]); 
    } 
} 
}; 

Moi Preprocesuj i autocompleter funkcje:

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("#", ''); 
}; 

i używać w HTML:

<ul data-bind="tagit:{tags:Tags, autocomplete:{source:TagAutocompleter, delay:250, minLength: 2}, options:{preprocessTag: TagProcessor}}"> 
</ul> 
+0

Również Naprawiono błąd w ramach aktualizacji, dzięki czemu może korzystać z danych, które są w obserwowalne od początek –

+0

Czy możesz dołączyć fragment kodu dla TagAutocompleter i TagProcessor? – NullReference

+1

Zaktualizowałem oryginalną odpowiedź z tymi + drobnymi aktualizacjami :) –