2017-10-19 12 views
0

Je collection de Tags (tableau de ficelle)Observable est changé pour un seul viewmodel

Pour chacun des Tags je créer knock-out viewmodel TagsViewModel

var TagsViewModel = function() { 
    var vm = this; 

    vm.showTags = ko.observable(false); 

    window.shouter.subscribe(function(newValue) { 
    vm.showTags(newValue); 
    }, vm, 'toggleReviewTags'); 
} 

Et j'ai une autre « toggler » pour montrer/cache les tags dans une autre vue partielle. Pour cela j'ai créé viewmodel séparé TagFiltersViewModel et utiliser knock-out PubSub pour communiquer avec TagsViewModel

var TagFiltersViewModel = function() { 
    var vm = this; 

    vm.isTagsVisible = ko.observable(false); 

    vm.isTagsVisible.subscribe(function(newValue) { 
    window.shouter.notifySubscribers(newValue, 'toggleReviewTags'); 
    }); 

    vm.toggleTags = function() { 
    vm.isTagsVisible(!vm.isTagsVisible()); 
    } 
} 

Chaque TagsViewModel je lie au contenant avec id calculé "tag-container-"+ {tagId}
et pour chaque faire prochaine chose

var element = document.getElementById(tagModel.tagsContainer); 
ko.cleanNode(element); 
ko.applyBindings(new TagsViewModel(tagModel), element); 

problème - localement, une seule étiquette de la collection est affichée après avoir cliqué sur le bouton bascule. J'ai créé jsFiddle, mais là je ne peux pas reproduire mon problème.

Des pensées quel est le problème dans mon cas?

+0

Il est un peu difficile de vous aider si votre violon fonctionne comme prévu ... (vous avez oublié d'inclure KO cependant). Le seul morceau de code sujet aux erreurs est les appels répétés à 'cleanNode' et' applyBindings'. Bien que ce ne soit pas * faux *, il est généralement préférable de créer un wrapper viewmodel et des liens 'with' ou' foreach' pour accéder à vos composants séparés. – user3297291

+0

@ user3297291, knock-out que j'ai ajouté comme resourse, pas de jsfiddle dropdown. Et à propos de wrapper - je voudrais, mais dans mon cas, il est difficile et provoque des bugs ... – demo

Répondre

0

Je suggère de faire quelque chose comme ce qui suit, cela devrait rendre la gestion beaucoup plus facile.

Il peut y avoir une raison particulière pour laquelle vous liez chaque étiquette séparément à l'aide de la méthode theapplyBindings, mais vous devrez élaborer à ce sujet.

var arrayOfTags = ['tag1', 'tag2', 'tag3']; 
 

 
var ViewModel = function() { 
 
    var self = this; 
 

 
    // Return an array TagsViewModels using the map method 
 
    this.Tags = ko.observableArray(arrayOfTags.map(function(tag) { 
 
    return new TagsViewModel(tag); 
 
    })); 
 

 
    // Observable to track if all tags are hidden/shown 
 
    this.TagsVisible = ko.observable(true); 
 

 
    // Loop through tags, show and set flag to true 
 
    this.ShowTags = function() { 
 
    self.Tags().forEach(function(tag) { 
 
     tag.Visible(true); 
 
    }) 
 
    self.TagsVisible(true); 
 
    }; 
 

 
    // Loop through tags, hide and set flag to false 
 
    this.HideTags = function() { 
 
    self.Tags().forEach(function(tag) { 
 
     tag.Visible(false); 
 
    }) 
 
    self.TagsVisible(false); 
 
    }; 
 

 
}; 
 

 
var TagsViewModel = function(name) { 
 
    this.Name = ko.observable(name) 
 
    this.Visible = ko.observable(true); 
 
}; 
 

 
var model = new ViewModel(); 
 
ko.applyBindings(model);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script> 
 

 
<button data-bind="click: ShowTags, visible: !TagsVisible()">Show Tags</button> 
 
<button data-bind="click: HideTags, visible: TagsVisible">Hide Tags</button> 
 

 
<hr> 
 

 
<!-- ko if: Tags() --> 
 
    <!-- ko foreach: Tags --> 
 
    <span data-bind="text: Name, visible: Visible"></span> 
 
    <!-- /ko --> 
 
<!-- /ko -->