2012-07-13 10 views
5

Używam knockoutjs do tworzenia widoku drzew podziału. Obok każdego węzła znajdują się trzy przyciski: 1) Nowe dziecko (dotyczy węzła obok 2) Usuń (Usuwa węzeł, który jest obok, oraz 3) Kopiuj, który kopiuje węzeł i wszystkie jego elementy podrzędne i tworzy nowy węzeł pod rodzicem.Usuwanie Self From obserwowalneArray w nokaucieJS

Mam przycisk Nowy, a teraz pracuję nad przyciskiem usuwania. Nie mogę sprawić, żeby działało, i zamiast robić coś pożytecznego, po prostu odświeża całą stronę. Oto kod:

Widok:

<h2>Skill & Weight Divisions</h2> 
     <span data-bind="text: tournamentname"></span><button data-bind="click: addDivision"><img src="new.png"/></button> 
     <ul data-bind="template: { name: 'divisionTemplate', foreach: divisions }"></ul> 

Szablon:

<script id="divisionTemplate" type="text/html"> 
    <li data-bind="style: {'background-color':color}"> 
     <input data-bind="value: name"/><button data-bind="click: addDivision"><img src="new.png"/></button><button data-bind="click: $parent.removeDivision"><img src="remove.png"/></button><button data-bind="click: $parent.copyDivision"><img src="copy.png"/></button> 
     <ul data-bind="template: { 'if': children, name: 'divisionTemplate', foreach: children }"></ul> 
    </li>  
</script> 

Widok Model i odpowiednią funkcję pomocnika:

function division(id, name, filter, children) { 
     this.id = ko.observable(id); 
     this.name = ko.observable(name); 
     this.filter = ko.observable(filter) 
     if(children){ 
      this.children = ko.observableArray(children); 
     }else{ 
      this.children = ko.observableArray(); 
     } 
     this.addDivision = function(){ 
      this.children.push(new division("", "", "")); 
     } 
     this.removeDivision = function(division){ 
      this.children.remove(division); 
     } 
     this.copyDivision = function(division){ 
      this.children.push(division); 
     } 
     this.color = randColor(); 
    }; 
    function tournamentViewModel(){ 
     var self= this; 
     self.tournamentname = ko.observable('NO NAME YET'); 
     self.districts = ko.observableArray([new district('Provo',1),new district('Salt Lake City',2),new district('St. George',3)]); 
     self.district = ko.observable(self.districts()[0]); 
     self.regions = ko.observableArray([new region('Utah',1),new region('Idaho',2)]); 
     self.region = ko.observable(self.regions()[0]); 
     self.location = ko.observable('WHEREVER YOU WANT'); 
     self.eventdate = ko.observable(''); 
     self.startTime = ko.observable(''); 
     self.image = ko.observable(); 
     self.flyer = ko.computed(function(){ 
      var flyerHTML = '<span style="text-align:center;padding:10px;"><h1>'+self.tournamentname()+'</h1><img src="'+self.image()+'"/><br/>'; 
      flyerHTML += 'District: ' + self.district().districtName + ' Region: ' + self.region().regionName+'<br><br>'; 
      flyerHTML += '<h2>WHEN: '+self.eventdate()+' '+self.startTime()+'</h2>'; 
      flyerHTML += '<h2>WHERE: '+self.location()+'</h2>'; 
      flyerHTML += '<img src="http://maps.googleapis.com/maps/api/staticmap?center='+encodeURI(self.location())+'&zoom=12&size=200x200&markers=color:blue%7Clabel:S%7C'+encodeURI(self.location())+'&maptype=roadmap&sensor=false"/>'; 
      return flyerHTML; 
     }, self); 
     self.clearImage = function(){ 
      self.image(''); 
     } 
     self.tournamentID = ko.computed(function(){return 't_'+self.district()+'_'+self.region()+'_'+self.eventdate()}, self); 
     self.pricingStructures = ko.observableArray([new pricingStructure(3,2.99), new pricingStructure(1,1.99)]); 
     self.removePricingStructure = function(pricingStructure){ 
      self.pricingStructures.remove(pricingStructure); 
     } 
     self.addPricingStructure = function(){ 
      self.pricingStructures.push(new pricingStructure("", "")); 
     } 
     self.promoCodes = ko.observableArray(); 
     self.promoTypes = ['%','$']; 
     self.removePromoCode = function(promoCode){ 
      self.promoCodes.remove(promoCode); 
     } 
     self.addPromoCode = function(){ 
      self.promoCodes.push(new promoCode("", ""));  
     } 
     self.divisions = ko.observableArray([new division(1, "Men","",[new division(2,"Gi"), new division(3,"No-Gi")])]); 
     self.addDivision = function(){ 
      self.divisions.push(new division("", "", "")); 
     } 

    } 
    ko.applyBindings(new tournamentViewModel()); 

Moje główne pytanie w tym wszystkim jest to: Czy istnieje sposób dostępu do macierzy nadrzędnej obiektu w celu usunięcia tego samego obiektu z tablicy? Z góry dziękuję za pomoc!

EDIT: Oto jsFiddle: http://jsfiddle.net/eqY7Z/ Jednak nie wydaje się działać w ogóle istnieje. Jeśli nie możecie tego zrobić, dołączę link do mojej strony, na której jest ona hostowana, abyście mogli się jej dobrze przyjrzeć.

+0

Chciałbym również dodać, że w pewnym momencie usunięto działające, ale tylko na dwa poziomy w dół. Coś głębszego nie działało.Jeśli będę pamiętał kod, który tam działał, dam ci znać. –

+1

możesz utworzyć jsfiddle dla tego? – HashCoder

+0

Muszę iść do pracy już teraz, ale podczas mojej przerwy odłożę jedną. –

Odpowiedz

2

Wziąłem twój pomysł i zrobiłem working fiddle, który zachowuje się dokładnie tak, jak to opisałeś. Nie chciałem, żeby ci się udało, przepraszam. Miał wiele rzeczy niezwiązanych bezpośrednio z twoim problemem, a to rozwiązanie jest na tyle ogólne, że inne osoby powinny móc z niego korzystać. Jeśli potrzebujesz pomocy w dostosowaniu, daj mi znać.

Należy zwrócić uwagę na funkcję klonowania. Twoja funkcja kopiowania nie jest głęboka i spowoduje, że wiele węzłów wskaże ten sam obiekt. Jeśli chcesz zaktualizować wartość węzłów, będzie ona propagować do swoich klonów. Knockout zapewnia poręczną głęboką kopię + rozwijanie obserwowalne z ko.toJS. Super przydatne.

JS:

var Node = function(name, children) { 
    var self = this; 
    self.name = ko.observable(name || 'NewNode'); 
    self.children = ko.observableArray(
    ko.utils.arrayMap(children || [], function(i) { 
     return new Node(i.name, i.children); 
    })); 
    self.newChild = function() { 
     self.children.push(new Node()); 
    }; 
    self.removeNode = function(node) { 
     self.children.remove(node); 
    }; 
    self.copyNode = function(node) { 
     var cloneNode = ko.toJS(node); 
     self.children.push(new Node(cloneNode.name, cloneNode.children)); 
    }; 
}; 

//Example data removed for brevity, see fiddle 
ko.applyBindings(new Node(data.name, data.children));​ 

HTML:

<button data-bind="click: newChild">NewNode</button> 
<ul data-bind="template: { name: 'treeTemplate', foreach: children}"> 
</ul> 

<script id="treeTemplate" type="text/html"> 
    <li> 
     <input data-bind="value: name" /> 
     <button data-bind="click: newChild">New Child</button> 
     <button data-bind="click: $parent.removeNode">Remove Node</button> 
     <button data-bind="click: $parent.copyNode">Copy Node</button> 
     <ul data-bind="template: { name: 'treeTemplate', foreach: children}"></ul> 
    </li> 
</script> 
​ 
+0

To wygląda świetnie, a wypróbuję to później wieczorem. Dla jasności, ponieważ wiem, że napisałeś to jako ogólną odpowiedź, w moim konkretnym przypadku węzły będą tym, co nazywam podziałami, prawda? –

+0

Tak. Węzeł jest powszechnym terminem dla elementu w drzewie. – Tyrsius

+0

Również dziękuję za rozwiązanie problemu z kopiowaniem. Miałem to zrobić po tym, jak pokonałem funkcję usuwania. Dzięki za uratowanie mnie mnóstwo czasu i nauczenie mnie dobrego nokautu javascript! –

1

udało mi się stworzyć wersję roboczą kodzie w następujący jsFiddle: http://jsfiddle.net/3eQNf/. Wydawało się zejść do 2 głównych zagadnień:

  1. Miałeś problem kontekstowe z wykorzystaniem „to” słowo kluczowe w swojej klasie podziału. Dodanie zmiennej własnej rozwiązało ten problem.

  2. Musisz dodać pojedynczy podział na poziomie katalogu głównego i powiązać go z jego dziećmi. To powoduje, że cała rekursja działa zgodnie z oczekiwaniami. Spowoduje to również usunąć potrzebę metody addDivision z dysku tournamentViewModel

Również FYI, musiałem dodać odcinki dla powiatu, regionu, a pricingStructure klas od tych, które nie zostały uwzględnione w kodzie próbki powyżej. Mam nadzieję że to pomoże.

+0

Dzięki za poinformowanie mnie, co było nie tak. Myślałem, że usunąłem kod regionu, regionu itp. No cóż. Zauważyłem jednak, że nie mogę skopiować podziału najwyższego poziomu z dostarczonym przez ciebie skrzypkiem, a kopiowanie faktycznie tworzy tylko pola tekstowe, które wskazują już istniejące obiekty. Wiem, że moje pytanie nie dotyczyło kopiowania, tylko chciałem ci o tym powiedzieć. –