Bien sûr, il est très facile de répondre à cette question, mais existe-t-il un moyen simple de déterminer si une propriété d'un modèle d'affichage masqué a changé?
Réponses
Trop de publicités?Utiliser des rallonges:
ko.extenders.trackChange = function (target, track) {
if (track) {
target.isDirty = ko.observable(false);
target.originalValue = target();
target.subscribe(function (newValue) {
// use != not !== so numbers will equate naturally
target.isDirty(newValue != target.originalValue);
});
}
return target;
};
Ensuite:
self.MyProperty= ko.observable("Property Value").extend({ trackChange: true });
Maintenant, vous pouvez inspecter comme ceci:
self.MyProperty.isDirty()
Vous pouvez également écrire un viewModel générique parcourant pour voir si quelque chose a changé:
self.isDirty = ko.computed(function () {
for (key in self) {
if (self.hasOwnProperty(key) && ko.isObservable(self[key]) && typeof self[key].isDirty === 'function' && self[key].isDirty()) {
return true;
}
}
});
... et ensuite, vérifiez au niveau de viewModel
self.isDirty()
Vous pouvez vous abonner aux propriétés que vous souhaitez surveiller:
myViewModel.personName.subscribe(function(newValue) {
alert("The person's new name is " + newValue);
});
Cela alertera lorsque personName changera.
Ok, vous voulez donc savoir quand quelque chose change dans votre modèle ...
var viewModel = … // define your viewModel
var changeLog = new Array();
function catchChanges(property, value){
changeLog.push({property: property, value: value});
viewModel.isDirty = true;
}
function initialiseViewModel()
{
// loop through all the properties in the model
for (var property in viewModel) {
if (viewModel.hasOwnProperty(property)) {
// if they're observable
if(viewModel[property].subscribe){
// subscribe to changes
viewModel[property].subscribe(function(value) {
catchChanges(property, value);
});
}
}
}
viewModel.isDirty = false;
}
function resetViewModel() {
changeLog = new Array();
viewModel.isDirty = false;
}
(je ne l'ai pas testé - mais vous devriez avoir l'idée)
Vous pouvez utiliser le plugin ci-dessous pour ceci:
https://github.com/ZiadJ/knockoutjs-reactor
Le code pour l'exemple vous permettra de garder une trace de tous les changements au sein de toute viewModel:
ko.watch(someViewModel, { depth: -1 }, function(parents, child) {
alert('New value is: ' + child());
});
PS: pour l'instant cela ne fonctionne pas avec subscribables imbriquée à l'intérieur d'un tableau, mais une nouvelle version qui prend en charge, il est sur le chemin.
Mise à jour: L'exemple de code a été mis à jour pour fonctionner avec v1.2b qui ajoute le support pour les éléments de tableau et subscribable-en-subscribable propriétés.
J'ai eu le même problème, j'ai besoin d'observer tout changement dans le viewModel, afin d'envoyer les données au serveur, Si quelqu'un est toujours interessé, j'ai fait quelques recherches et c'est la meilleure solution iv e a réussi à assembler:
function GlobalObserver(viewModel, callback) {
var self = this;
viewModel.allChangesObserver = ko.computed(function() {
self.viewModelRaw = ko.mapping.toJS(viewModel);
});
viewModel.allChangesObserver.subscribe(function() {
callback(self.viewModelRaw);
});
self.dispose = function() {
if (viewModel.allChangesObserver)
viewModel.allChangesObserver.dispose();
delete viewModel.allChangesObserver;
};
};
afin d'utiliser ce "global observateur":
function updateEntireViewModel() {
var rawViewModel = Ajax_GetItemEntity(); //fetch the json object..
//enter validation code here, to ensure entity is correct.
if (koGlobalObserver)
koGlobalObserver.dispose(); //If already observing the older ViewModel, stop doing that!
var viewModel = ko.mapping.fromJS(rawViewModel);
koGlobalObserver = new GlobalObserver(viewModel, Ajax_Submit);
ko.applyBindings(viewModel [ ,optional dom element]);
}
Notez que la fonction de rappel donnée (dans ce cas Ajax_Submit') sera tiré sur TOUT changement qui se produit sur le modèle de vue, donc je pense qu'il est vraiment recommandé de faire une sorte de mécanisme de délai pour envoyer de l'entité uniquement lorsque l'utilisateur a terminé de modifier les propriétés:
var _entitiesUpdateTimers = {};
function Ajax_Submit(entity) {
var key = entity.ID; //or whatever uniquely related to the current view model..
if (typeof _entitiesUpdateTimers[key] !== 'undefined')
clearTimeout(_entitiesUpdateTimers[key]);
_entitiesUpdateTimers[key] =
setTimeout(function() { SendEntityFunction(entity); }, 500);
}
Je suis nouveau sur le JavaScript et le knock-out cadre, (uniquement yestarday j'ai commencé à travailler avec ce magnifique cadre), donc ne soyez pas en colère contre moi si j'ai fait quelque chose de mal.. (-:
Espérons que cette aide!
J'ai adapté @Brett Green code et je l'ai étendu de manière à ce que nous puissions avoir AcceptChanges, marquant le modèle comme non sale, et disposant d'un moyen plus agréable de marquer les modèles comme étant traçables. Voici le code:
var viewModel = {
name: ko.observable()
};
ko.track(viewModel);