Reputation: 16282
i am learning Knockout js. so reading many article and code from various source. i just got a small code with Knockout js. i have confusion to understand few area in that code. which i will highlight and some one please help me to understand.
here is the full code
<ul data-bind="foreach: {data: links, afterAdd: $root.fadeIn, afterRemove: $root.fadeOut}">
<li>
<select>
<option>Homepege</option>
<option>Facebook</option>
</select>
<input type="text" />
<button class="close" data-bind="click: $root.removeLink">×</button>
</li>
</ul>
<a href="#" data-bind="click: addLink">Add Link</a>
function Link(id, url) {
var self = this;
self.id = id;
self.url = url;
}
function VenueCreateViewModel() {
var self = this;
self.links = ko.observableArray([new Link("", "")]);
//self.linksList = ko.observableArray(['Homepage11','Facebook']);
self.removeLink = function (link) {
self.links.remove(link)
}
self.addLink = function () {
self.links.push(new Link("", ""));
}
self.fadeIn = function (element, index, data) {
//$(element).fadeIn();
$(element).filter("li").delay(1000).fadeIn(1000);
}
self.fadeOut = function (element, index, data) {
$(element).filter("li").delay(1000).fadeOut(1000);
}
}
ko.applyBindings(new VenueCreateViewModel());
1)
see this code data-bind="foreach: {data: links, afterAdd: $root.fadeIn, afterRemove: $root.fadeOut}"
why one need to point a function name with $root keyword ?
i point function name in binding this way data-bind="foreach: {data : rows, beforeRemove : ElementFadeOut, afterAdd:ElementFadeIn}"
and it works.
so tell me when to refer or point a function name with $root keyword
?
2) i have some time seen people use $parent keyword. so tell me what is the difference between $root & $parent keyword
?
3) see this code self.links = ko.observableArray([new Link("", "")]);
why they push link object into observable Array
where we can simply push any string into links observable Array
?
4) they use fadeIn & fadeOut
$(element).filter("li").delay(1000).fadeOut(1000);
but why fadeout effect is not working...any clue ?
here is jsfiddle link from where any one can see and run full code http://jsfiddle.net/mfrsousa/2gt4K/3/
thanks
i have couple of question based on jsfiddle link supplied by @Super cool
1) why your refer firstName
property name in binding
<span data-bind="text:$data.firstName">
see the below code and this way i bind. here u can see i did not mention property name like first name or last name
<div id="dash" data-bind="foreach: {data : rows, beforeRemove : ElementFadeOut, afterAdd:ElementFadeIn}">
<div data-bind="text:$data">
</div>
so please tell me why your mention property name in binding like first name or last name
??
2) i have seen the jsfiddle link http://jsfiddle.net/supercool/2gt4K/27/
there i have seen the usage of $parent $root keyword
usage but do not understand what is the difference between these keywords $parent & $root keyword
from your example it seems both keywords $parent & $root keyword
works same way. can you tell me what is the difference between ?
Upvotes: 0
Views: 2394
Reputation: 6045
Let me try .
$root refers to root content of viewModel always even $data represents the same but it tend to change based on the view you build .
$parent will look one step ahead of $data i.e if you have multiple looping instances
VM:
var mainLoopModel = function () {
var self = this; // Root Level scope
self.mainloop = ko.observableArray([{
'firstName': 'jhon'
}, {
'firstName': 'sam'
}]);
self.lastName = ko.observable('peters');
}
ko.applyBindings(new mainLoopModel());
View:
<div data-bind="foreach:mainloop">
$data Value: <span data-bind="text:$data.firstName"></span>
<span data-bind="text:$data.lastName"></span> --(1)
$parent Value: <span data-bind="text:firstName"> </span>
<span data-bind="text:$parent.lastName"></span>
$root Value: <span data-bind="text:firstName"></span>
<span data-bind="text:$root.lastName"></span>
</div>
Note: If you remove $data before lastName in note (1) you get undefined error because mainloop dont have lastName , root model has lastName so you have to access using parent or higher level
sample fiddle for you here
self.links = ko.observableArray([new Link("", "")]);
here we are assigning data rather pushing . yes we can use normal strings but we should sacrifice 2-way binding and your idea works well if you just binding the data to view which is where user cannot change .
A small mistake there you should be using beforeRemove
not afterRemove
.
working demo here
Refer the docs here which is crystal clear to understand.
Upvotes: 0
Reputation: 10296
The forEach
binding creates a new child binding context. When the binding renders an item, the context's $data
property against which binding expressions are evaluated by default refers to the list item rather than your view-model. Therefore if you need to refer to your view-model inside a foreach binding you need to reference the parent binding context - which in many cases is equal to the root binding context. You can find a thorough explanations of Knockout's Binding Context here.
Again, read this
Because Link
is a class that combines an url with an id.
What is not working? If by not working you refer to the element remaining in the DOM after it has faded, please be advised that you are responsible for removing the element from the DOM after your animation has completed. Again, read the documentation.
Upvotes: 2