I want switching my organisation's application from Knockout to Vue, and some concept are missing or I misunderstand vueJs philosophy. So I can't reproduce the same behavior.
From what I've read, VueJs is really focused on component.
Each component manage is own piece of DOM.
https://fr.vuejs.org/v2/guide/reactivity.html
https://fr.vuejs.org/v2/guide/list.html
... (i read most of this guide page's before starting to type in my keyboard :p)
This behavior is nice for simple component that need to be shared across but in my case it's a bit frustrating because I need some module to be linked (see at the end with my question about context)
I've read another great article (https://jes.al/2017/05/migrating-from-knockoutjs-to-vuejs/) about "knockout to Vuejs transition" but it lacks of so specific details.
For example : its explain that "subscribe" (in KO) can be replaced by "watch" (in Vue) but doesn't explain "when" we can apply these watchers (see my questions at the end)
Here is a very small code extraction that could summarize most of my specific needs.
Html
<div id="app">
<div data-bind="text: title"></div>
<i data-bind="visible: changeTracker.hasChanges">save your change dude !!</i>
<div data-bind="with: model">
<!-- the binging "with" allow us to move context to model for the current node and prevent typing "model." each time (ex: model.prop1, modeld.pro2,) -->
<label data-bind="text: name"></label>
<input type="text" data-bind="value: firstName"/>
<span data-bind="text: $parent.nameAndFirstName">
<!-- "$parent" allow us to access vm context itself -->
<input type="text" data-bind="value: city"/>
</div>
<div>
<button data-bind="click: changeTracker.undo, enabled: changeTracker.hasChanges"></button>
<button data-bind="click: saveData, enabled: changeTracker.hasChanges"></button>
</div>
</div>
Javascript
var changeTrackerVM_Factory = function(){
var self = {};
self.initialState = null; // no need to be ko.observable since it's used for internal manipulation only
// flag that will tell the UI that modification exist
self.hasChanges = ko.observable(false);
self.init = function(modelToTrack){
// some piece of code .... subscribe ... and so on
}
self.undo = function(){
// some piece of code that revrt the object to it's initial state
};
return self;
};
var userVM_Factory = function(){
var self = {};
// data from-to database
self.model = {
id: "", //-- don't need to be observable since it's not rendered and not modifiable
name: ko.observable(""),
firstName: ko.observable(""),
city: ko.observable("")
};
self.nameAndFirstName = ko.computed(function(){
return self.model.name() + "-" + self.model.firstname();
});
// build the custom tracker module
self.changeTracker = changeTrackerVM_Factory();
self.init = function(){
//some ajaxRequest
$.ajax(....).then(function(data){
// map recieved datas
self.model.name(data.name);
......
// apply custom observation AFTER data mapping
self.model.city.subscribe(function(newvalue){
alert("yeaah !! YOU changed the city value");
});
// apply the "custom tracking module" used to show the state in the UI
self.changeTracker.init(self.model);
});
}
self.save = function(){
// some piece of code to send to DATABASE
}
return self;
};
// initialise the relation between the UI and the VM
var userVM = userVM_Factory();
ko.applybinding(userVM , "#app");
If i want to convert this code to vueJS and i have the same behavior i need to answer :
how can i track only few properties of "model" (i'am sure it's possible since such an used libray would have been concerned by perf optimization)
how can i initiate "watch" ONLY AFTER first initialisation (and prevent the "alert" popup at the begining)
As you can see, i have not "one module for his DOM piece" ex: changeTracker.hasChanges is used at the top and at the bottom of the DOM
if i use component to manage "model" only with its own piece of DOM.. how can i use $parent inside ???