use variable in knockout js html - javascript

I want to use variable in html find but in can't find any way to do it. I tried this but not working for me.
<!--ko foreach: { data: test(), as: 'method'}-->
<!--ko var isValid = test_title;
/ko !-->
<tr class="row"><th colspan="4" data-bind="text: isValid" class="test_title"></th></tr>
<!-- /ko !-->
First Experience with KO.

You can't write javascript in a ko comment, but you can write it in the binding value.

Related

knockout if and text binding

I'm trying to create a simple component in Knockout (3.3.0):
ko.components.register('test', {
viewModel: function() {
this.test = 'hello'
},
template:
`<span data-bind='if: 1, text: test'></span>`
});
ko.applyBindings();
See fiddle.
Now when I instantiate a <test></test> somewhere else, I get an error:
Multiple bindings (if and text) are trying to control descendant bindings of the same element. You cannot use these bindings together on the same element.
Is this really not possible? This would be like the most basic functionality to incorporate if you ask me. I know I could use <!-- ko text --> but what about setting other attributes like src and using if at the same time?
OK I found the (or at least, one possible) solution: Use <!-- ko if --><!-- /ko -->. This way, the template can be written like
<!-- ko if: 1-->
<span data-bind='text: test'></span>
<!-- /ko -->
I still don't think it's perfect, in Vue I would just do <span v-if='1'>{{text}}</span> bam done, but I guess not everything in this world can be as awesome as Vue...

Knockout bind function in IF statement

I need to get a value from the ViewModel using a value from an object located in a loop in the view/page.
<!-- ko foreach: ExtendedItems() -->
<tr>
<!-- ko foreach: PriceGroups() -->
<!-- ko if: DeductibleAmount() === $root.FindDeductibleValue($parent.Provider()) -->
<td> --Content-- </td>
<!-- /ko -->
<!-- /ko -->
</tr>
<!-- /ko -->
I have a function in the ViewModel that finds the correct value:
self.FindDeductibleValue = function (provider) {
return self.SelectedDeductibles.findObs('Provider', { Provider: provider }).Value();
}
This function works fine when I call it from the ViewModel, but I get "Cannot read property 'Value' of null at viewModel.self.FindDeductibleValue" when I try to use it in the view/page in the IF statement.
I've replaced $parent.Provider() with a number just to make sure that $parent.Provider() is not null, but it doesn't change the error I receive.
Is it not possible to use a function in an IF statement this way?
The issue here is "binding context". Couple things first though.
EDIT:
I just noticed that the method FindDeductibleValue() receives
something other than the currently iterated item, like knockout does
automatically. And the code within it seems a little strange. Can you
please post the full view models you're working with? I'm not
convinced there's enough context to answer the problem correctly here.
I would use the $parents array not $root in case the depth or pattern ever changes.
You don't need to invoke your observables in your bindings, knockout will do this for you. <!-- ko foreach: ExtendedItems --> instead of <!-- ko foreach: ExtendedItems() -->.
The main error you're encountering is a binding context issue, whereby when invoking the method from within the loop, you are essentially within a child context of the viewmodel. Unfortunately, JavaScript isn't able to tell you this. But it is telling you the problem. The child item doesn't have a Value property. In order to fix this you need to bind to the correct context I believe the code would be:
$parents[0].FindDeductibleValue.bind(null, $parent.Provider())

knockout.js - use a for binding within a with

I want to do something like the html below, where I am using a with binding on the table, but within the table I want to do a foreach loop and access each element of the foreach.
When I do it this way, the th tags don't work, and it will only work if I remove the with binding from the html.
How can I get it to work (i.e. render the table headers with values 1, 2, 3)?
<table data-bind="with: myData">
<tr>
<th><input type="checkbox" value=""></th>
<!-- ko foreach: [1,2,3] -->
<th data-bind="html: $data"></th>
<!-- /ko -->
</tr>
<!-- other stuff here -->
</table>
This can happen, if myData is not an observable and is empty, without any value assigned to it.
I have tried your code here and it is working properly.

Knockoutjs "foreach" equivalent for non array objects

I've been using Knockoutjs for a while, but there is something I haven't been able to solve and I'm sure there must be an easy way to do it.
I really like nesting objects, using "foreach" on the html and then accessing each of these object's property directly. That way it keeps the code simple and clear.
The problem is that sometimes I use an observableArray to hold only one element in order to use the "foreach way" that I mention.
Is there other way of saying "I'm now within this scope", same behaviour as "foreach".
Example: here
<body>
<!-- ko foreach: people -->
<div data-bind="text: name">name</div>
<!-- /ko -->
<br />
<!-- here I would like to say I'm inside 'importantPerson' and therefore name is a property of importantPerson -->
<!-- <div data-bind="text: name">name (important)</div> -->
<br />
</body>
You are looking for the with binding:
The with binding creates a new binding context, so that descendant elements are bound in the context of a specified object.
So you code would look like this:
<body>
<!-- ko foreach: people -->
<div data-bind="text: name">name</div>
<!-- /ko -->
<br />
<!-- ko with: importantPerson -->
<div data-bind="text: name"></div>
<!-- /ko -->
<br />
</body>
Demo JSFiddle.

Event parameter not defined for Knockout click binding using Firefox

I am getting this JS error: ReferenceError: event is not defined when I try to pass the event object to click binding when I use Firefox 23. Everything works fine under Chrome
Here the code:
<!-- ko foreach: entries -->
<tr data-bind="click: function(){ $parent.expandRow($data, event) }">
...
</tr>
<!-- /ko -->
vm.entries.expandRow = function(entry, event){
...
}
Here the solution from github.com/knockout/knockout/issues/752
<!-- ko foreach: entries -->
<tr data-bind="click: function(data, event){ $parent.expandRow($data, event) }">
...
</tr>
<!-- /ko -->
Under Firefox event is not defined on the window object, instead it needs to be passed to the function.
I know that this is a pretty old question, but still if someone is looking for the answer then I achieved it in the following way:
<div id="this-element" data-bind="click : function(){ $root.clicked(event)}">
</div>
Following code (clicked function) is written in the ViewModel for the page:
this.clicked= function (event) {
console.log(event.currentTarget.id);
}
Knockout 3.4.2
jQuery 3.2.1

Categories

Resources