The problem is that i need to call a function every single time that a route change to a specific state, lets say i have chatController and i have to fire a() every second but if i exit the controller i have to stop a() and when i'm back to chatController i have to restart a()
My code:
$scope.stop = $interval(yourOperation, 1000);
var dereg = $rootScope.$on('$locationChangeSuccess', function() {
$interval.cancel($scope.stop);
dereg();
});
function yourOperation() {
console.log('$location', $location.$$url)
console.log('test');
}
Works fine executing every single and stops when the controller change, but it doesn't work anymore if i go back, i tried with ng-init() function but only fires the first time that the controller start, i need it always when i'm on a specifict controller.
1] If it is state then you can use following event to call function every time when you back to state
$scope.$on('$ionicView.enter',function(){
$scope.callingFunctionName();
});
Here you may need to add following attribute in app.js state declaration
cache: false
2] In case you are using modal then controller will automatically get initialize.
just need to call function like following -
$scope.callingFunctionName();
hi this code must be in the controller
// .... controller
$scope.stop = $interval(yourOperation, 1000);
function yourOperation() {
console.log('hi')
}
$scope.$on('$destroy',function () {
$interval.cancel($scope.stop);
})
Related
I'm not a JavaScript guy, so I'm not sure how to get this working.
I'm using SmartWizard in one of my projects. The original SmartWizard code was extended by someone that is no longer available and is not around to ask.
What I want to do is to leave his code in place as it is and to just access the functions within his class to move the user forward or back in the wizard process.
As far as I can tell, the functions that perform the actions I need are called goForward and goBackward. How to access them though from outside his class?
Here is the goForward function:
SmartWizard.prototype.goForward = function(){
var nextStepIdx = this.curStepIdx + 1;
if (this.steps.length <= nextStepIdx){
if (! this.options.cycleSteps){
return false;
}
nextStepIdx = 0;
}
_loadContent(this, nextStepIdx);
};
There are also other functions within his code that I would like to access such as 3 callbacks that can be triggered when the user clicks the Next, Prev and Finish buttons. Below are those 3 callbacks that I need to access.
$.fn.smartWizard.defaults = {
onLeaveStep: null, // triggers when leaving a step
onShowStep: null, // triggers when showing a step
onFinish: null, // triggers when Finish button is clicked
};
Can someone shed some light on what I need to do here to access them?
$('#wizard').smartWizard({
...
...
// Events
onLeaveStep: function () {
// Do Your stuff on step leave
}, // triggers when leaving a step
onShowStep: : function () {
// Do Your stuff on step show
}, // triggers when showing a step
onFinish: : function () {
// Do Your stuff on finish
} // triggers when Finish button is clicked
});
These methods looks like instance methods, not class methods.
For example, goForward is referencing instance variables (e.g., curStepIdx, steps), so you cannot call it as a class method. You'll need to call it on an instantiated object.
I'm having the most difficult time trying to find a way to make sure the parent scope's collection is updated with the saved information from a modal.
The parent has a collection of event speakers, and the modal adds one speaker to the event. I want for the new speaker to be added to the page once the modal OK button is clicked.
The data is saved and the modal closes, but the model isn't updated unless I refresh the page.
Here's my controller method that updates the collection of speakers. $scope.speakers gets bound to a repeating object in the page.
$scope.updateSpeakersList = function () {
factory.callGetService("GetSpeakers?eventId=" + $scope.event.eventId)
.then(function (response) {
var fullResult = angular.fromJson(response);
var serviceResponse = JSON.parse(fullResult.data);
$scope.speakers = serviceResponse.Content;
LogErrors(serviceResponse.Errors);
},
function (data) {
console.log("Unknown error occurred calling GetSpeakers");
console.log(data);
});
}
Here's the promise where the modal should be calling the previous method, and therefore updating the page.
$scope.openModal = function (size) {
var modalInstance = $modal.open({
templateUrl: "AddSpeakerModal.html",
controller: "AddSpeakerModalController",
size: size,
backdrop: "static",
scope: $scope,
resolve: {
userId: function() {
return $scope.currentUserId;
},
currentSpeaker: function () {
return ($scope.currentSpeaker) ? $scope.currentSpeaker : null;
},
currentSessions: function () {
return ($scope.currentSpeakerSessions) ? $scope.currentSpeakerSessions : null;
},
event: function () {
return $scope.event;
},
registration: function() {
return $scope.currentUserRegistration;
}
}
});
modalInstance.result.then(function (savedSpeaker) {
$scope.savedSpeaker = savedSpeaker;
$scope.updateSpeakersList();
}, function () {
console.log("Modal dismissed at: " + new Date());
});
};
Why is the model not updating?
It's hard to know for sure without having a minimal example that reproduces the problem, but your problem might be that you are updating a 'shadow scope'. This is a pecularity in Javascript which causes the object to be copied instead of modified.
Try adding $scope.$apply() after doing the change in updateSpeakerList().
Check this post and then play around with it.
AngularJS - Refresh after POST
What worked for me was pushing the data to my scope on success then setting the location, so after posting new data mine looked like:
$scope.look.push(data);
$location.path('/main');
The issue here isn't that my data wasn't updating necessarily... the real issue is that the moments that I was attempting to update it were the wrong moments for how my app is put together. I was attempting to update the underlying model BEFORE the updates were available, without realizing it. The AJAX calls were still in progress.
Within my modal, when OK is clicked, it runs through a few different GETs and POSTs. I was calling the update outside of these calls, assuming that it would be called sequentially once the AJAX calls were done. (This was wrong.)
Once I moved the $scope.updateSpeakersList() call to be within the final AJAX success call to my factory, everything appears to be working as desired.
I want to trigger a new Chat once the variable newChat is being changed like this:
$rootScope.newChat = {
roomId: roomId,
friendId: friendId
};
in my ChatController I $watch the variable like this:
$rootScope.$watch('newChat', function (data) { /*do stuff*/ }
this works on my page after the first reload of the page without any problems. But for the first load this $watch gets triggered twice which causes issues on some other parts of the chat.
I checked the value of newChat. Both times the value is exactly the same. No other parts of my application use the $rootScope.newChat Variable
Why is that and how can I fix this?
Every watch will get triggered when a $digest cycle runs. What you need to do is check the new value vs. the old value.
$rootScope.$watch('newChat', function (newValue, oldValue) {
if(newValue !== oldValue){
/*do stuff*/
}
});
I fixed this problem like this
$rootScope.$watch('someValue', function (){
/* rewrite into a new scope */
$scope.someValue = $rootScope.someValue;
});
$scope.$watch('someValue', function (){/*To do*/});
I'm new to AngularJS, coming from a jQuery background. At the moment I take my first steps and create some sample pages with Angular.
Now I wanted to achieve some thing like this: Think of an app with two "pages". First is the main page with some text etc and on the other theres running a timer. The timer should start from 0 and count up to infinite by every second, right when you started the app. This is the first thing I cannot achieve. My timer only starts when I navigate to the second page.
The second problem: When the timer is running, I want to navigate through all the pages in the app and the timer should still count in the background. Well, at the moment it does run in the background, but every time when I navigate to the page with the timer, it seems like there gets opened another task that count the timer up, resulting in a very infrequent and faster counting.
On my index html I use ng-view to insert the other pages by ngRoute. This works fine.
My timer page looks like this:
<div ng-controller="TimeCtrl">
<p>Counter: {{counter.getValue()}}</p>
</div>
Then I wrote a timer controller for my app:
app.controller("TimeCtrl", function($scope, $interval, Counter){
$scope.counter = Counter;
$interval(function(){
$scope.counter.update();
}, 1000);
});
And there's a counter factory:
app.factory("Counter", function () {
this.counter = 0;
var self = this;
return {
update : function () {
self.counter++;
},
getValue : function () {
return self.counter;
}
}
});
I would appreciate any help as Angular does not come that easy for me in the beginning.
Instead of using the $interval on the controller, use it on the service/factory:
app.factory("Counter", function ($interval) {
this.counter = 0;
var self = this;
$interval(function(){
self.update();
}, 1000);
return {
update : function () {
self.counter++;
},
getValue : function () {
return self.counter;
}
}
});
This way if your TimeCtrl gets destroyed (for whatever reason), the counter will still get incremented.
Note also that every time you re-open a page that creates a new TimeCtrl, a new interval will also be defined. That's why you are getting that "infrequent and faster counting".
Regarding it being loaded only on the second page, make sure that you add the Counter service as dependency to your main controller, so that the service gets instantiated immediately (otherwise the counter will not start). If you do not have a main controller, use a run block:
app.run(function(Counter) {
// just inject the Counter so that it gets instantiated
})
I'm trying to understand why this code execute an alert() 3 times:
$scope.logout = function () {
$rootScope.auth.$logout();
$rootScope.$on('$firebaseSimpleLogin:logout', function(event) {
alert("Logged out"); // This appears 3 times.
});
}
But this just one:
$scope.logout = function () {
$rootScope.auth.$logout();
alert("Logged out"); // This JUST appears once.
}
I understand that the second approach is direct; first execute one line, then the other one. But what if $logout fails and the app displays that the operation was successful when it doesn't? Due to that possibility I'm using $firebaseSimpleLogin:logout event to handle the situation properly. Sadly, it isn't working as I imagined.
What could be wrong?
It's difficult to say without seeing the rest of the application, but there is one error: in the first code sample, you're attaching another event listener every time $scope.logout is called--e.g., if you call it twice, the next time the event fires it'll alert twice. Click it again, and the next time the event fires, you'll get three alerts. You should move the registration of the event listener outside of the function call:
// put this anywhere that's only called once
app.run(function($rootScope) {
$rootScope.$on("$firebaseSimpleLogin:logout", ...);
});
// elsewhere
$scope.logout = function() {
$rootScope.auth.$logout();
};
// You could also unregister the function when you're done with it instead
app.controller("AuthController", function($scope, $rootScope) {
var unregListener = $rootScope.$on("$firebaseSimpleLogin:logout", ...);
$scope.$on("$destroy", unregListener);
$scope.logout = function() { ... };
});