2012-07-13 127 views
5

我正在使用knockoutjs創建一個分區樹視圖。在每個節點旁邊將有三個按鈕:1)新的子節點(適用於它旁邊的節點2)刪除(刪除它旁邊的節點,3)複製,複製節點及其所有子節點,並創建一個新節點父節點下的節點。從knockoutJS中刪除自我observableArray

我已經得到了新的按鈕,現在我正在處理刪除按鈕。我似乎無法讓它工作,而不是做任何有用的事情,它只是刷新整個頁面。下面的代碼:

查看:

<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> 

模板:

<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> 

視圖模型和適當的輔助功能:

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

我在這一切的主要問題是:有沒有辦法訪問對象的父數組,以便從數組中移除該對象?先謝謝您的幫助!

編輯:這是一個jsFiddle:http://jsfiddle.net/eqY7Z/但它似乎並沒有在那裏工作。如果你們無法完成這項工作,我會在鏈接到我的網站的地方放置它,這樣你就可以好好看看它。

+0

另外我想補充一點,我確實得到了刪除工作,但只有兩個級別。任何更深入的東西都行不通。如果我能記住在那裏工作的代碼,我會讓你知道的。 – 2012-07-13 04:09:48

+1

你可以爲此創建一個jsfiddle嗎? – HashCoder 2012-07-13 11:06:25

+0

我現在必須去上班,但在休息時間我會放一個。 – 2012-07-13 14:25:51

回答

2

我把你的想法做了一個working fiddle,其行爲與你所描述的完全相同。我不想嘗試將你排除在外,對不起。它有很多與您的問題沒有直接關係的東西,而且這個解決方案通用性足以讓其他人能夠使用它。如果您需要幫助,請讓我知道。

需要注意的一件事是克隆功能。您的複製功能不深,並且會導致多個節點指向同一個對象。如果您要更新節點值,它會傳播到它的克隆。 Knockout提供了一個方便的深度複製+解包觀察與ko.toJS。超級有用。

的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

這看起來不錯,今晚晚些時候我會試試看。要明確一點,就像我知道你把這個作爲一個普通答案寫下來的那樣,在我的具體情況下,節點就是我所稱的分區,對嗎? – 2012-07-13 16:35:54

+0

是的。節點是樹中項目的通用術語。 – Tyrsius 2012-07-13 16:36:42

+0

也非常感謝您解決複印功能。我打敗了remove函數後就這麼做了。感謝您節省了我大量的時間,並教我一些很好的挖掘javascript! – 2012-07-13 16:36:58

1

我能創造你的代碼在下面的jsfiddle的工作版本:http://jsfiddle.net/3eQNf/。它似乎回落到2個主要問題:

  1. 你有一個背景問題,在您的部門級使用「本」關鍵字。添加自變量解決了這個問題。

  2. 您需要添加一個根級別劃分並綁定到其子級。這使得所有遞歸按預期工作。這樣做也刪除了addDivision方法需要把你的tournamentViewModel的

此外,僅供參考,我需要添加存根爲你的地區,區域,以及因爲這些pricingStructure類不包括在上面的示例代碼。希望這可以幫助。

+0

謝謝你讓我知道什麼是錯的。我以爲我已經清理了區域,地區等代碼。好吧。我確實注意到,雖然我不能用你提供的小提琴複製頂級分區,但實際上覆制只是創建指向已經存在的對象的文本框。我知道我的問題不是關於複製,只是想爲你指出。 – 2012-07-13 19:24:12

相關問題