Does knockout re-evaluate inside a virtual element that's been removed - javascript

My current template is something like following:
<!-- ko 'if': condition -->
<ul data-bind="foreach: items">
...
</ul>
<!-- /ko -->
<!-- ko ifnot: condition -->
<ul data-bind="foreach: items">
...
</ul>
<!-- /ko -->
Does it make sense to change it into following
<ul data-bind="foreach: items">
<!-- ko 'if': $parent.condition -->
...
<!-- /ko -->
<!-- ko ifnot: $parent.condition -->
...
<!-- /ko -->
</ul>
My actual use case is to have both a list view and a grid view - because their doms are different, I can't just swap some classes on the parent ul block.
I wonder which approach is better?

I think that your original approach is likely preferable, as there will be less overhead with evaluating the if and ifnot bindings for each item (which includes saving off the child elements as a "template").

Related

Knockout JS - list items without the parent <ul> element

I have a simple demo application with a foreach binding of "li" elements inside an "ul" element.
<ul data-bind="foreach: sortedItems">
<li>
<div>
<span data-bind="text: name">
</div>
</li>
</ul>
Is there a way to create the same binding without a parent element?
Yes, you can use knockout's virtual element syntax for this purpose. See the first example on this page.
<!-- ko foreach: sortedItems -->
<li> ... </li>
<!-- /ko -->

I got TypeError: transclude is not a function and also can't able to bind select options value in select2 in angularjs

I got one plunker code for multi select2 drop down using angularjs. It works fine except the option value is not bound in select option while running with my code.
I have linked the plunker demo below but the code in plunker executed fine without any errors but somehow I got this error while run with my code...
console error:
**"TypeError: transclude is not a function"**
plunker link:
http://plnkr.co/edit/juqoNOt1z1Gb349XabQ2?p=preview
and here is the include this demo module with my module like below,
var gateApp = angular.module('gateApp', ["demo","angucomplete"])
i am battling with this error anyone can give me suggestion.
For your reference Rendered HTML code in console:
<ul class="ui-select-choices ui-select-choices-content select2-results ng-scope" repeat="color in availableColors | filter:$select.search">
<li class="ui-select-choices-group" ng-class="{'select2-result-with-children': $select.choiceGrouped($group) }">
<div ng-show="$select.choiceGrouped($group)" class="ui-select-choices-group-label select2-result-label ng-binding ng-hide" ng-bind="$group.name">
</div>
<ul role="listbox" id="ui-select-choices-0" ng-class="{'select2-result-sub': $select.choiceGrouped($group), 'select2-result-single': !$select.choiceGrouped($group) }" class="select2-result-single"><!-- ngRepeat: color in $select.items -->
<!-- ngIf: $select.open -->
<li role="option" id="ui-select-choices-row-0-0" class="ui-select-choices-row ng-scope select2-highlighted" ng-class="{'select2-highlighted': $select.isActive(this), 'select2-disabled': $select.isDisabled(this)}" ng-repeat="color in $select.items" ng-if="$select.open" ng-click="$select.select(color,false,$event)"><div class="select2-result-label ui-select-choices-row-inner" uis-transclude-append="">
</div>
</li><!-- end ngIf: $select.open -->
<!-- end ngRepeat: color in $select.items -->
<!-- ngIf: $select.open -->
<li role="option" id="ui-select-choices-row-0-1" class="ui-select-choices-row ng-scope" ng-class="{'select2-highlighted': $select.isActive(this), 'select2-disabled': $select.isDisabled(this)}" ng-repeat="color in $select.items" ng-if="$select.open" ng-click="$select.select(color,false,$event)">
</li><!-- end ngIf: $select.open --><!-- end ngRepeat: color in $select.items --><!-- ngIf: $select.open -->
</ul>
</li>
</ul>
The version of angular is probably too old. I had this same issue when using v1.2.16 and ui-select requires 1.2.18 minimum.
https://github.com/angular-ui/ui-select/wiki/Getting-Started
I got this error as well. What resolved the issue for me was to take the ng-if out of the root element and put it in the child elements that needed it.

if and ifnot knockout statement in the same line

Hi guys i am trying to do a knockout statement which changes certain factors if it is classed as true or false. My problem is i need a if and a ifnot statement in the same line to output the correct result.
Example codes:
<!-- ko if: User().loggedin -->
<li><a href="#"><p class="Score">1</p><p style="display:none;"
>First</p></a></li>
<!--/ko-->
Now i need a ifnot statement within that statement as it has a couple of different ways it can go.
<!-- ko ifnot: Goal -->
So how do i mix them both up so they can be outputed on the same line. Example below (which i know doesnt work.) but may get you to understand completely what i want.
<!-- ko if: User().loggedin -->
<!-- ko ifnot: Goal -->
<li><a href="#"><p class="Score">1</p><p style="display:none;"
>First</p></a></li>
<!--/ko-->
<!--/ko-->
All the observable's work fine.
Thanks
Other than massively-confusing indentation, your second example is fine; here it is with the confusion removed:
<!-- ko if: User().loggedin -->
<!-- ko ifnot: Goal -->
<li><a href="#"><p class="Score">1</p><p style="display:none;"
>First</p></a></li>
<!--/ko-->
<!--/ko-->
alternately:
<!-- ko if: User().loggedin && !Goal() -->
<li><a href="#"><p class="Score">1</p><p style="display:none;"
>First</p></a></li>
<!--/ko-->
<!--/ko-->
...assuming Goal is an observable (remove the () if not).

ng-repeat did not show same as type each manually on screen

Yesterday, I see this question on the stackoverflow:
No spacing between bootstrap-labels with ng-repeat
The Question owner only want to get a solution , so I open a new question to ask cause.
Here is the plnkr
<span class="label label-primary" ng-repeat="tag in tags">{{tag}}</span>
This will be compiled to
<!-- ngRepeat: tag in tags -->
<span class="label label-primary ng-scope ng-binding" ng-repeat="tag in tags">panel</span>
<!-- end ngRepeat: tag in tags -->
<span class="label label-primary ng-scope ng-binding" ng-repeat="tag in tags">angular</span>
<!-- end ngRepeat: tag in tags -->
<span class="label label-primary ng-scope ng-binding" ng-repeat="tag in tags">bootstrap</span>
<!-- end ngRepeat: tag in tags -->
I try to type each manually
<!-- ngRepeat: tag in tags -->
<span class="label label-primary">panel</span>
<!-- end ngRepeat: tag in tags -->
<span class="label label-primary">angular</span>
<!-- end ngRepeat: tag in tags -->
<span class="label label-primary">bootstrap</span>
<!-- end ngRepeat: tag in tags -->
And, this two have the same css which I check on the Google Chrome Developer Tool.
I am very curious why this could cause different view?
Angular will rewrite the html for ng-repeat. In your manual case, if you remove the newlines and make it all squished together, you get the same effect as the first one. Chrome is also breaking it up and showing them as newlines whereas in reality its not the case.
Just open the same plnkr in firefox and in the HTML panel, check the "Show Whitespace" and you will see that there are no whitespaces in the one that angularjs rewrote. Your manual case will have whitespaces which lead to the spacing between the labels.

Ignore section reference with Sammy.js

Twitter bootstrap accordion not working with Sammy.js
Is a similar question but was never answered.
I am creating an affixed Twitter Bootstrap side nav-list and using has based href's but when I click on them Sammy is trying to catch the routes. Since I am dynamically creating the Id's and href's I can prevent them from ever matching an existing route but it constantly hits the console with errors. I am sure in production they won't show up but is there anything that can be done to prevent this?
<ul class="nav nav-list affix">
<!-- ko foreach: sections -->
<li class="nav-header"><span data-bind="text: navDesc"></span></li>
<!-- ko foreach: paragraphs -->
<li><a data-bind="attr: { href: '#' + navProp() }"><span data-bind="text: navDesc"></span> <i class="icon-chevron-right"></i></a></li>
<!-- /ko -->
<!-- /ko -->
</ul>
I know this will be fixed in the next version of Durandal but just checking any other options.
Durandal 1.2 provides a guardRoute method, which will allow you to intercept the call before it reaches sammy.
Check out How to handle / ignore a bad route with durandal? for more information.

Categories