AngularJS directive with isolate scope, ng-repeat, and controllerAs
function directive() {
return {
restrict: 'E',
template: '<button ng-repeat="x in j.array" ng-click="j.set(x)">{{x}}</button>',
replace: true,
//scope: {},
bindToController: {
array: '=',
answer: '='
},
controller: function() {
var j = this;
j.set = function(data) {
j.answer = data;
};
},
controllerAs: 'j'
};
}
When I uncomment scope and create an isolate scope the directive no longer works. I'm trying to determine why.
Normally I still have access to the controllerAs in an ng-repeat
, in this example when I lose it it's still available on $parent.j
. I think there are 3 solutions.
Solution 1 is to leave it not in isolate scope.
Solution 2 would be to convert every reference to j
inside the repeat to $parent.j
.
Solution 3 is that there is some way to use j
without having to use $parent
that I'm unaware of.
1 answer
See also questions close to this topic
-
How can I apply dynamic locale change in AngularJS tests?
In an AngularJS application using
angular-dynamic-locale
, I want to test locale-dependent code in different locales.I am trying to change the locale in an asynchronous setup. In previous Jasmine versions, this was done with a latch function; these are now deprecated and replaced with the
done
callback.beforeEach(function (done) { inject(function ($injector) { tmhDynamicLocale = $injector.get('tmhDynamicLocale'); console.log('setting locale to French...'); tmhDynamicLocale .set('fr-fr') .then(function () { console.log('locale set.'); done(); }) .catch(function (err) { done.fail('failed to set locale:', err); }); }); });
The promise returned by
tmhDynamicLocale.set
remains pending forever, and the setup times out.Looking at the innards of
tmhDynamicLocale
shows that the locale change is scheduled, but never actually applied:// This line runs $rootScope.$applyAsync(function() { // But this callback doesn't storage[storagePut](storageKey, localeId); $rootScope.$broadcast('$localeChangeSuccess', localeId, $locale); deferred.resolve($locale); });
I have tried calling
$browser.defer.flush
and digesting/applying the root scope, but the locale change callback is still not executed.How can I change the locale in this test suite?
Plunker, with logs in
tmhDynamicLocale
added for clarity. -
Angularjs: strange table sorting
Our team is building a table widget in ServiceNow and is experiencing some weird table sorting.
<table id="print_table" class="display table table-striped table-hover"> <thead> <tr> <th ng-show="c.options.case_number"> <a href="javascript:void(0)" title="Case Number" id="caseNumber" ng-click="sortType = 'number'; sortReverse = !sortReverse"> <span ng-show="sortType == 'number' && !sortReverse" class="fa fa-arrow-down"></span> <span ng-show="sortType == 'number' && sortReverse" class="fa fa-arrow-up"></span> ${Case Number} </a> </th> <th ng-show="c.options.last_name"> <a href="javascript:void(0)" title="Last Name" id="lastName" ng-click="sortType = 'lastName'; sortReverse = !sortReverse"> <span ng-show="sortType == 'lastName' && !sortReverse" class="fa fa-arrow-down"></span> <span ng-show="sortType == 'lastName' && sortReverse" class="fa fa-arrow-up"></span> ${Last Name} </a> </th> <th ng-show="c.options.first_name"> <a href="javascript:void(0)" title="First Name" id="firstName" ng-click="sortType = 'firstName'; sortReverse = !sortReverse"> <span ng-show="sortType == 'firstName' && !sortReverse" class="fa fa-arrow-down"></span> <span ng-show="sortType == 'firstName' && sortReverse" class="fa fa-arrow-up"></span> ${First Name} </a> </th> <th ng-show="c.options.case_short_description"> <a href="javascript:void(0)" title="Short Description" id="shortDescription" ng-click="sortType = 'short_description'; sortReverse = !sortReverse"> <span ng-show="sortType == 'short_description' && !sortReverse" class="fa fa-arrow-down"></span> <span ng-show="sortType == 'short_description' && sortReverse" class="fa fa-arrow-up"></span> ${Short Description} </a> </th> <th ng-show="c.options.start_date"> <a href="javascript:void(0)" title="Start Date" id="startDate" ng-click="sortType = 'start_date'; sortReverse = !sortReverse"> <span ng-show="sortType == 'start_date' && !sortReverse" class="fa fa-arrow-down"></span> <span ng-show="sortType == 'start_date' && sortReverse" class="fa fa-arrow-up"></span> ${Start Date} </a> </th> <th ng-show="c.options.work_location"> <a href="javascript:void(0)" title="Work Location" id="workLocation" ng-click="sortType = 'location'; sortReverse = !sortReverse"> <span ng-show="sortType == 'location' && !sortReverse" class="fa fa-arrow-down"></span> <span ng-show="sortType == 'location' && sortReverse" class="fa fa-arrow-up"></span> ${Work Location} </a> </th> <th> <a href="javascript:void(0)" title="Status" id="status" ng-click="sortType = 'status'; sortReverse = !sortReverse"> <span ng-show="sortType == 'status' && !sortReverse" class="fa fa-arrow-down"></span> <span ng-show="sortType == 'status' && sortReverse" class="fa fa-arrow-up"></span> ${Status} </a> </th> </tr> <tr id="filters"> <!--<th></th>--> <th ng-repeat="item in c.filters track by $index"> <multiselect title="Select {{item.label}}" id={{item.label}} ng-model="c[item.model]" options="c[item.unique_list]" show-search="true" show-unselect-all="true" ng-change="c.filter()" placeholder="Select {{item.label}}" show-tooltip="true" classes-btn="'btn-info btn-block'"> </multiselect> </th> </tr> </thead> <tbody> <tr ng-click="c.onWidget('batch_qa_form_list',item.sys_id, item.short_description);" ng-repeat="item in c.onbCase | orderBy:sortType:sortReverse | filter:searchTable track by $index" ng-if="item.case_visible"> <td ng-if="c.options.case_number" title="{{item.number}}">{{item.number}}</td> <td ng-if="c.options.last_name" title="{{item.last_name}}">{{item.last_name}}</td> <td ng-if="c.options.first_name" title="{{item.first_name}}">{{item.first_name}}</td> <td ng-if="c.options.case_short_description" title="{{item.short_description}}">{{item.short_description}}</td> <td ng-if="c.options.start_date" title="{{item.start_date}}">{{item.start_date}}</td> <td ng-if="c.options.work_location" title="{{item.location}}">{{item.location}}</td> <td> <i ng-if="item.all_approved" class="fa fa-check-circle success"></i> <i ng-if="!item.all_approved" class="fa fa-exclamation-circle warning" uib-tooltip="{{item.number_pending}} items pending review" tooltip-placement="left" title=""></i> </td> </tr> </tbody> </table>
The sorting works well with the first column (Case Number), but once we get into the First Name, Last Name, and Start Date fields, the sorting becomes really weird. We've put in very strange Names to test things out and this is what we're seeing:
The above screenshot shows the table sorted by Last Name, but you can see that the entries are sorted in a very strange way. We've read that there might be case sensitivity, so we've tried putting all Last Names to lowercase by doing {{item.last_name | lowercase}}, but the sorting remains the same.
Any ideas on how to fix this? Thanks!
-
ServiceNow: table sort doesn't work with option schema
Our team is building a widget in ServiceNow that shows a list of cases with columns that can be chosen via option schema. The option schema consists of true/false fields for each column and the html looks like this:
<th ng-if="c.options.case_number"> <a href="javascript:void(0)" title="Case Number" id="caseNumber" ng-click="sortType = 'number'; sortReverse = !sortReverse"> <span ng-show="sortType == 'number' && !sortReverse" class="fa fa-arrow-down"></span> <span ng-show="sortType == 'number' && sortReverse" class="fa fa-arrow-up"></span> ${Case Number} </a> </th>
The issue we're running into involves the option schema breaking the sort function. If we take away the ng-if="c.options.case_number", the sort works great. However, with that ng-if in, the sort refuses to work.
Any ideas how to fix this? Thanks!
-
Why is AngularJs not rendeting directive on page change?
I found this treeview directive
//////////////////////////////////////////////////////////////////////////////// /// TREEVIEW ////////////////////////////////////////////////////////////////// angular.module('myApp.treeView', []).directive('treeView', function($compile) { return { restrict : 'E', scope : { localNodes : '=model', localClick : '&click' }, link : function (scope, tElement, tAttrs, transclude) { var maxLevels = (angular.isUndefined(tAttrs.maxlevels)) ? 10 : tAttrs.maxlevels; var hasCheckBox = (angular.isUndefined(tAttrs.checkbox)) ? false : true; scope.showItems = []; scope.showHide = function(ulId) { var hideThis = document.getElementById(ulId); var showHide = angular.element(hideThis).attr('class'); angular.element(hideThis).attr('class', (showHide === 'show' ? 'hide' : 'show')); } scope.showIcon = function(node) { if (!angular.isUndefined(node.children)) return true; } scope.checkIfChildren = function(node) { if (!angular.isUndefined(node.children)) return true; } ///////////////////////////////////////////////// /// SELECT ALL CHILDRENS // as seen at: http://jsfiddle.net/incutonez/D8vhb/5/ function parentCheckChange(item) { for (var i in item.children) { item.children[i].checked = item.checked; if (item.children[i].children) { parentCheckChange(item.children[i]); } } } scope.checkChange = function(node) { if (node.children) { parentCheckChange(node); } } ///////////////////////////////////////////////// function renderTreeView(collection, level, max) { var text = ''; text += '<li ng-repeat="n in ' + collection + '" >'; text += '<div class="wrapper-treeview" style="padding: 10px" ng-class="{bgFirsr: $first && showIcon(n), bgChildren: !showIcon(n), bgBrown: !$first && showIcon(n), lastBorderRadius: $last}" >'; text += '<span ng-show=showIcon(n) class="show-hide" ng-click=showHide(n.id)><i class="zmdi zmdi-plus icon-color"></i></span>'; text += '<span ng-show=!showIcon(n) style="padding-right: 13px"></span>'; // if (hasCheckBox) { // text += '<input class="tree-checkbox" type=checkbox ng-model=n.checked ng-change=checkChange(n)>'; // } text+= '<span class="icon-color" style="cursor: pointer" ng-click=localClick({node:n})><i class="zmdi zmdi-eye"></i></span>' text += '<label style="vertical-align: bottom;">{{n.name}}</label></div>'; if (level < max) { text += '<ul ng-class="{show: $first && showIcon(n), hide: !$first && showIcon(n)}" id="{{n.id}}" class="" ng-if=checkIfChildren(n)>'+renderTreeView('n.children', level + 1, max)+'</ul></li>'; } else { text += '</li>'; } return text; }// end renderTreeView(); try { var text = '<ul class="tree-view-wrapper">'; text += renderTreeView('localNodes', 1, maxLevels); text += '</ul>'; tElement.html(text); $compile(tElement.contents())(scope); } catch(err) { tElement.html('<b>ERROR!!!</b> - ' + err); $compile(tElement.contents())(scope); } } }; });
And i call it in the html in this way
<tree-view id="treeview" checkbox click="myClick(node)" class="ng-cloak" model="nodes"></tree-view>
if i refresh the page with
F5
i can see everything ok. But if I change page of the website and i click again the page of the treeview doesn't work. It doesn't render the directive. There are no errors on the console. I tried to addng-cloak
directive and class but nothing changed -
Auto focus next input field and move to previous field on backspace in ionic android
I'm having an OTP page with input fields with "tel" type. It should not allow any special character and if valid number is pressed it should move to next field and if backspace is pressed, focus should move to previous field.
so i'm using directive using selector to not allow special character and another keyup event to move to next/previous field based on the input length. But when user enter special character, directive returns the empty string and assumes that its a backspace empty and then mistakenly move to the previous field. Any help would be appreciated.
It would be better if i can do autofocus using directive itself.Here is my code below.
HTML:
<ion-row [formGroup]="otpForm"> <ion-col col-2> <ion-item> <ion-input text-center formControlName="otp1" [ngClass]="setClasses('otp1')" class="padding-left" #otp1 type="tel" [(ngModel)]="forgotOTP.otp1" (input)='onChangeTime(forgotOTP.otp1)'[max-length]='1' (keyup)="next($event,otp2,otp1)" is-number > </ion-input> </ion-item> </ion-col> <ion-col col-2> <ion-item> <ion-input text-center formControlName="otp2" [ngClass]="setClasses('otp2')" class="padding-left" #otp2 type="tel" [(ngModel)]="forgotOTP.otp2" (input)='onChangeTime(forgotOTP.otp2)' [max-length]='1' (keyup)="next($event,otp3,otp1)" is-number> </ion-input> </ion-item> </ion-col> </ion-row>
Directive:
import { Directive, HostListener,EventEmitter, Input,Output } from '@angular/core'; import { Platform } from "ionic-angular"; /** * Generated class for the IsNumberDirective directive. * * See https://angular.io/api/core/Directive for more info on Angular * Directives. */ @Directive({ selector: '[is-number]' // Attribute selector }) export class IsNumberDirective { //private regex: RegExp = new RegExp(/^\d*[0-9]\d*$/g); private regex: RegExp = new RegExp(/^[0-9]*$/); @Input('is-number') numberValue:number; private specialKeys: Array<string> = [ 'Backspace', 'Tab', 'End', 'Home' ]; @Output() ngModelChange:EventEmitter<any> = new EventEmitter(); private oldValue:any; constructor(public platform:Platform) { console.log('Hello IsNumberDirective Directive'); } @HostListener('keypress', ['$event']) onKeyPress(event) { if (this.specialKeys.indexOf(event.key) !== -1) { return; } console.log("current"+this.numberValue); let current:string = this.numberValue.toString(); this.oldValue=event.target.value; let next: string = current.concat(event.key); console.log("next"+next); debugger; if (next && !String(next).match(this.regex)) { event.preventDefault(); } } @HostListener('paste', ['$event']) onPaste($event) { this.onKeyPress($event) } @HostListener('keyup',['$event']) onKeyup(event) { debugger; const element = event.target as HTMLInputElement; let newValue = element.value; console.log("new value in number"+element.value); if (this.platform.is('android')) { console.log("test regex "+!this.regex.test(newValue) ) if (!this.regex.test(newValue)) { element.value = newValue.slice(0, -1); }else{ element.value = newValue; } this.ngModelChange.emit(element.value); } } }
KeyUp Event:
next(event,el,prevel) {
let regex: RegExp = new RegExp(/^[0-9]*$/); let value=event.target.value; if(this.platform.is('android')){ if(regex.test(value)){ if (event.target.value.length == 1) { el.setFocus(); }else if(el.value.length == 0) { prevel.setFocus(); } } }else if(this.platform.is('ios')){ if (this.specialKeys.indexOf(event.key) !== -1) { if(el.value.length == 0) { prevel.setFocus(); } } if(String(event.key).match(regex) != null){ if (event.target.value.length == 1) { el.setFocus(); }else if(el.value.length == 0) { prevel.setFocus(); } } }
-
How can i get Json Data if its having in particular Name
Here im having data Like
""{\"resultStatus\":\"success\",\"message\":\"AUTH-040010: Successfully logout user\",\"language\":\"en\",\"region\":\"us\",\"securityToken\":\"C29F32A5-CF46-4CE8-B1DF-4FBC207ABA19|13|1550120060454\",\"userName\":\"John\",\"organisationId\":1,\"isSearch\":false,\"productId\":1,\"productKey\":\"fAyhhy455Hh4d52c\",\"menuKey\":\"LOG\",\"pageDto\":{\"selectedPage\":1,\"totalCount\":0,\"recodsPerPage\":25},\"menuMasterDtoList\":{},\"validated\":true}Redirectdata=https://192.168.10.19:8089/iauth/access/login?productId=1&productKey=f8cc80d…a24d52c&redirectUrl=http://172.16.1.135:458/Enquiry/openenquiries&Message= Success&MessageType=1""
in this Url How can i get Redirectdata Url
JSON.stringify(d.data) By using this i convert that string in Json
But
JSON.stringify(d.data.Redirectdata)
This is Giving me undefind Please help me how can i get Redirectdata Url