2017-03-15 59 views
0

我想添加一個髒標誌到我的淘汰賽js模型(我期望它是一個簡單的任務),該標誌將更新時,任何屬性被更改。當任何屬性更改使用與ko.mapping時淘汰js更新髒標記

我在這裏發佈之前完成了一些研究,發現大多數答案指向this blog post這裏也有一個提示鏈接到帖子,我試圖遵循,但沒有成功。

我也嘗試過使用jquery來監聽輸入或select元素的變化,但是當輸入被填充時觸發onpage加載,因此標誌將始終設置爲dirty。

我的模型和例子之間的區別是我使用自動映射器

在這個例子就說明Itemdirty標誌。如何在使用自動映射器時複製此內容? (我已經加入我的JSON模式的情況下,它有助於提供一個 「最佳」 的解決方案)的例子

的JS

ko.dirtyFlag = function(root, isInitiallyDirty) { 
var result = function() {}, 
    _initialState = ko.observable(ko.toJSON(root)), 
    _isInitiallyDirty = ko.observable(isInitiallyDirty); 

result.isDirty = ko.computed(function() { 
    return _isInitiallyDirty() || _initialState() !== ko.toJSON(root); 
}); 

result.reset = function() { 
    _initialState(ko.toJSON(root)); 
    _isInitiallyDirty(false); 
}; 

return result; 
}; 

function Item(id, name) { 
    this.id = ko.observable(id); 
    this.name = ko.observable(name); 
    this.dirtyFlag = new ko.dirtyFlag(this); 
} 

var ViewModel = function(items) { 
this.items = ko.observableArray([ 
    new Item(1, "one"), 
    new Item(2, "two"), 
    new Item(3, "three") 
]); 

this.save = function() { 
    alert("Sending changes to server: " + ko.toJSON(this.dirtyItems)); 
}; 

this.dirtyItems = ko.computed(function() { 
    return ko.utils.arrayFilter(this.items(), function(item) { 
     return item.dirtyFlag.isDirty(); 
    }); 
}, this); 

this.isDirty = ko.computed(function() { 
    return this.dirtyItems().length > 0; 
}, this); 
}; 

ko.applyBindings(new ViewModel()); 

我的JSON對象

{"PropertyID":0,"BulletPoints":["test 1","test 2","test 3"],"BriefDescription":"Some test desc","TakeOnAppointmentDate":"0017-03-02T12:05:00","Rooms":null,"TenureLengthOfLease":10,"TenureLengthOfService":10,"GroundCharges":11.0,"Directions":"go here then there","KeyHolderName":"Name","KeyHolderReference":"very nice","IsDisplayToPublic":true,"UploadToRightMove":false,"UploadToOnTheMarkert":false,"UploadToPrimeLocation":false,"RightMoveCost":1000.0,"EpcCost":100.0,"FloorPlanCost":2.0,"RoomIdentifier":null,"CoverIdentifier":null,"CoverPath":null,"PreviewUrl":null,"EpcReportPdf":null,"FloorPlan1":null,"FloorPlan2":null,"DisplayFrom":185.000,"DisplayTo":200.000,"SelectedSalePriceOptionId":3,"IsHidden":null,"AddressLine1":null,"NumberOfBedrooms":5,"NumberOfBathrooms":3,"NumberOfReceptionrooms":2,"Tenures":[{"Id":1,"Description":"Freehold"},{"Id":2,"Description":"LeaseHold"}],"SelectedTenureId":2,"ViewingInstructions":[{"Id":1,"Description":"Accompanied viewings with prior notice"},{"Id":2,"Description":"Vacant property"},{"Id":3,"Description":"Vendor to do viewings"}],"SelectedViewingInstructionId":2,"SaleStates":[{"Id":1,"Description":"For Sale"},{"Id":2,"Description":"Sold"},{"Id":3,"Description":"SSTC"},{"Id":4,"Description":"To Let"}],"SelectedSaleStateId":2,"UnderOffers":[{"Id":0,"Description":"No"},{"Id":1,"Description":"Yes"}],"SelectedUnderOfferId":1,"SalePriceOptions":[{"Id":1,"Description":"Asking Price"},{"Id":2,"Description":"Guide Price"},{"Id":3,"Description":"Offers Over"},{"Id":4,"Description":"In the region of"},{"Id":5,"Description":"Auction guide"}],"BlobItems":[]} 

回答

1

在所有你需要的全球髒旗的最基本的實現是三件事

  • 狀態變量(布爾標誌)以保持髒狀態
  • 根對象上使用ko.toJS或ko.toJSON
  • 訂閱功能時所計算的屬性改變
以更新狀態變量計算屬性

如果您的視圖模型是建立與ko.mapping它可能是這個樣子:

var viewModel = function(jsonData){ 
    var self = this; 

    ko.mapping.fromJS(jsonData, {}, this); 

    self.isDirty = ko.observable(false); 
    self.toJS = ko.computed(function(){ 
    return ko.toJS(self); 
    }); 
    self.toJS.subscribe(function(value){ 
    self.isDirty(true); 
    }); 
} 

jsFiddle

之後,您可以添加額外的複雜性來存儲初始toJS()結果,並將其與新值進行比較,以查看數據是否真的發生了更改或者是否只是將其設置回相同的數據。

正如博客繼續說,但它不是最好的方式來做到這一點。任何更改都會導致計算結果通過遍歷ViewModel中的整個可觀察樹來重新計算,這會導致代價高昂。

這是我剛纔使用的另一個版本,它只評估第一次更改,然後在之後返回dirty = true。我很確定我也從Ryan Niemeyer那得到了這個,但我不記得在哪裏。我在你引用的博客上看不到一個非常喜歡它的人。

var viewModel = function(jsonData){ 
    var self = this; 

    ko.mapping.fromJS(jsonData, {}, this); 

    this.dirtyCheck = ko.computed({ 
    read: function() { 
     if (!self.isDirty){ //property doesn't exist yet 
     var json = ko.toJSON(self); //trigger a subscription to all observable properties. 
     } else { 
     self.isDirty(true); //If this is being evaluated then by definition something has changed. 
     } 
     return; 
    } 
    }); 
    this.isDirty = ko.observable(false); //only add the property after the computed has been initialized 
} 
+0

感謝您的幫助。此行'self.toJS = ko.computed((=){> { return ko.toJS(self); });'需要改爲'self.toJS = ko.computed(function(){ return ko.toJS(self); },this);'讓它爲我工作。我很想知道它們之間有什麼不同,以及爲什麼需要更改(當你在jsfiddle中顯示它工作時) – tony09uk

+1

哎呦,我以爲我抓住了所有這些,但我錯過了那一個。這是一個ecma腳本6的箭頭函數,可能在您使用的JavaScript版本中不受支持。 –

相關問題