Notice: The Monaca & Onsen UI Community Forum is shutting down.
For Onsen UI bug reports, feature requests and questions, please use the Onsen UI GitHub issues page. For help with Monaca, please contact Monaca Support Team.
Thank you to all our community for your contributions to the forum. We look forward to hearing from you in the new communication channels.
lazy-repeat refresh method is undefined
-
Hello I have an Angular JS application where a list is defined as follows
<ons-page ng-controller="AllItemsController"> <ons-list> <ons-list-item ons-lazy-repeat="lazyLoadDelegate" class="list__item__line-height" ng-class="{selected_list_row:isItemSelected(item),selected:item.selected}"> <span>{{item.name}}</span> </ons-list-item> </ons-list> </ons-page>
The controller and the delegate are defined as follows
(function () { 'use strict'; angular .module('MyApp') .controller('AllItemsController', AllItemsController); AllItemsController.$inject = ['$scope']; AllItemsController($scope) { $scope.lazyLoadDelegate = { configureItemScope: function(index, itemScope) { if(index < itemsList.length ){ itemScope.item = $scope.itemsList[index]; } }, countItems: function() { return $scope.itemsList.length; }, calculateItemHeight: function() { return 44; } }; $scope.$on(EventManager.EVT_ALL_ITEMS_FETCHED, function(event,data){ $scope.lazyLoadDelegate.refresh(); $scope.$apply(); }); }// AllItemsController })();
When the event fires and $scope.lazyLoadDelegate.refresh is called I get an error that refresh method is undefined.
Examining the $scope.lazyLoadDelegate variable in the debugger shows that the refresh method is indeed not there
Also when I put breakpoints in any delegate methods they are not hit.
I use Onsen UI v 2.10.5 and Angular.js v1.6.9
What am I missing??
Thanks
Andy
-
I’m not that familiar with the AngularJS compilation process, but the short answer is that the code in the controller is run before the
onsLazyRepeat
directive is compiled. WhenonsLazyRepeat
is compiled, it exposes therefresh
method so any code in the controller that runs immediately won’t be able to userefresh
.I think the solution is to check when the
EventManager.EVT_ALL_ITEMS_FETCHED
event is firing - it must be before compilation has happened.Let me know if this isn’t enough information to solve the problem and I will look into the compilation process in more detail.
-
The refesh method is not used immediately but only when the data is loaded from the server which takes at least a couple of seconds
Also I made a test where I just basically do exactly as in the sample i.e set the item count to some number, i.e 100, and in configurItemScope just doitemScope.item = "item" + index;
Still the list is empty.
Perhaps it’s some library that I’m missing? Or version incompatibility?
Thanks
Andy
-
Hmmm that’s strange your test isn’t working. Can you try inserting the code exactly from the playground example and see if that works? https://onsen.io/playground/?framework=angular1&category=reference&module=lazy-repeat
The only thing I can think of right now is that your code uses
$scope
whereas the playground example is usingController as controller
to reference the scope. Either is fine but both can cause problems so it’s worth checking they’re not accidentally both getting used somewhere.
-
No luck
SImplified my code as much as possible. It looks like this now
lazylist.html<ons-page ng-controller="ListController as list"> <ons-toolbar> <div class="center">Lists</div> <div class="right"> <ons-toolbar-button ng-click="list.doRefresh()">Refresh</ons-toolbar-button> </div> </ons-toolbar> <ons-list> <ons-list-item ons-lazy-repeat="list.delegate">{{ item }}</ons-list-item> </ons-list> </ons-page>
The listcontroller.js
angular.module('MyApp') .controller('ListController', function() { this.delegate = { configureItemScope: function(index, itemScope) { itemScope.item = 'Item ' + index; }, countItems: function() { return 10000; }, calculateItemHeight: function() { return ons.platform.isAndroid() ? 48 : 44; } }; this.doRefresh=function(){ this.delegate.refresh();//fails because refresh is not defined } });
The only remaining difference between the sample and my code is the way onsen framework is initialized
The sample usesons.bootstrap() .controller('ListController', function() .....
whereas my code uses
angular.module('MyApp') .controller('ListController', function()....
Could this be the problem?
My app main module is defined in another file as follows(function () { 'use strict'; var MyApp= angular.module('MyApp', ['onsen','ngCordovaOauth','rzModule', 'swipe']) .run(run); run.$inject = ['$rootScope']; function run($rootScope) { //app init } ons.ready(function() { // init plugins }); })();
-
From the code you provided, I can’t see what would be causing the problem.
Do the list items themselves show up? (i.e. you get ‘Item 1’, ‘Item 2’, ‘Item 3’, not ‘{{ item }}’). If the list items don’t show up it’s probably because Onsen isn’t loaded properly or you have a typo somewhere.
I don’t think it’s an Onsen version problem because I tried 2.10.1, 2.10.5 and 2.10.6 and they all worked for me.
I also don’t think it’s caused by using
angular.module
instead ofons.bootstrap
because I got it working fine withangular.module
.There are a few other things you might be able to try:
- If it’s an open source project, put the project on GitHub and I’ll clone it and take a look at it.
- If it’s not an open source project but you don’t mind sharing some of the code, make the smallest possible working example and put it on GitHub.
- If it’s a Monaca project, contact Monaca support. You’ll need a paid plan but they’ll clone your project and figure out why it’s not working.
-
This is not an open source project .
One thing that I’m suspicious of is the way the project is set up.
It started as a Monaca project online IDE but then was copied locally and development continued. So the project index.html file does not inclde onsenui.js,angular.js etc. but instead includes loader.js
However all other framework elements work just fine. The project uses ons-list, ons-tabbar, ons-navigator, ons-modal, etc and everything works,lazy-repeat is the only one thing that does not.
Perhaps I neeed to revisit the way the project is organized ,get rid of the loader.js and use standard onsenui.js, angular.js and whatever else may be needed.
Can you point me to a sample Onsen Angular JS skeleton project?
Thanks
Andy
-
@heel_curve5, in Local Kit, create a new project and select the type you want.
-
Thank you so much for pointing me to that tool. I was able to get the lazy list to work - created a skeleton Angular JS project,added the lazy load sample code to it and it worked!
However here is another problem.
It only works if the app is bootstrapped with my app=ons.bootstrap()…etc etc, like in the sample. My app is structured differently. I have a main module that is defined like thismain-module.js
(function () { 'use strict'; var MyApp= angular.module('SmartConApp', ['onsen,'ngCordovaOauth','rzModule', 'swipe']) .run(run); run.$inject = ['$rootScope']; function run($rootScope, { LogIt("APP MAIN"); // app initialization } ons.ready(function() { LogIt("Onsen UI is ready!"); // init plugins }); })();
The problem is that ons-ready is never called and neither is the run function
Any ideas?
Thank you so much for help
-
It might be that you don’t have
ng-app
defined in your HTML. That was one thing that tripped me up when I tried to convert the example to useangular.module
instead ofons.bootstrap
.
-
@emccorson said in lazy-repeat refresh method is undefined:
app
Aha!
That was it! Now it works
Thank you all very much for help!
Andy
-
A melhor pousada de Campos do Jordão