In the following code i am trying to change to another page on click and want to pass the object i how can i do it. In the following code i get it as undefined.how to go about this
<button ng-href="#/page1" value="{{i.display}}"></button>
app.controller("ctrls",['$scope','$location',function($scope,$location){
$scope.func = function(i) {
$scope.var=i
$location.path("/rel");
};
]);
app.controller("ctrls",'$scope',function($scope) {
console.log($scope.var) //undefined
]);
Pages normally have controller(s), a service can be created to share data between pages ( by injecting service in associated controllers). Like:
app.factory('myService', function() {
var savedData = {}
function set(data) {
savedData = data;
}
function get() {
return savedData;
}
return {
set: set,
get: get
}
});
In your controller A:
myService.set(yourSharedData);
In your controller B:
$scope.desiredLocation = myService.get();
Happy Helping!
Use a service (best) https://docs.angularjs.org/guide/services
Or $rootScope (bad, but simpler) https://docs.angularjs.org/api/ng/service/$rootScope
Related
I need to execute functions of some controllers when my application ends (e.g. when closing the navigator tab) so I've thought in a service to manage the list of those functions and call them when needed. These functions changes depending on the controllers I have opened.
Here's some code
Controller 1
angular.module('myApp').component('myComponent', {
controller: function ($scope) {
var mc = this;
mc.saveData = function(objectToSave){
...
};
}
});
Controller 2
angular.module('myApp').component('anotherComponent', {
controller: function ($scope) {
var ac = this;
ac.printData = function(objects, priority){
...
};
}
});
How to store those functions (saveData & printData) considering they have different parameters, so when I need it, I can call them (myComponent.saveData & anotherComponent.printData).
The above code is not general controller but the angular1.5+ component with its own controller scope. So the methods saveData and printData can only be accessed in respective component HTML template.
So to utilise the above method anywhere in application, they should be part of some service\factory and that needs to be injected wherever you may required.
You can create service like :
angular.module('FTWApp').service('someService', function() {
this.saveData = function (objectToSave) {
// saveData method code
};
this.printData = function (objects, priority) {
// printData method code
};
});
and inject it wherever you need, like in your component:
controller: function(someService) {
// define method parameter data
someService.saveData(objectToSave);
someService.printData (objects, priority);
}
I managed to make this, creating a service for managing the methods that will be fired.
angular.module('FTWApp').service('myService',function(){
var ac = this;
ac.addMethodForOnClose = addMethodForOnClose;
ac.arrMethods = [];
function addMethodForOnClose(idModule, method){
ac.arrMethods[idModule] = {
id: idModule,
method: method
}
};
function executeMethodsOnClose(){
for(object in ac.arrayMethods){
ac.arrMethods[object].method();
}
});
Then in the controllers, just add the method needed to that array:
myService.addMethodForOnClose(id, vm.methodToLaunchOnClose);
Afterwards, capture the $window.onunload and run myService.executeMethodsOnClose()
i have a service as follows
angular.module('starter.service')
.factory('authService', function($http) {
var service = {};
service.GetByUsername = function() {
return $http.get('/js/user.json');
}
return service;
})
i just need to know two things,
1. why its is declaring a object named service ?
2.its a service for getting an object, what changes should i change to add another function to post a object(do it in the same code)? dont remove current functionality.
You are using the factory method to create a service, so you need to create an object and return it (Dependency Injection will make sure this object is only instantiated once so it is used as a singleton).
Whether this object you are creating is called "service" or any other way, it doesn't matter, it will work anyway.
As Shankar shown in his example, adding more methods to your service is as easy as adding more methods to the object you are declaring. To clarify the example, I'll add the argument you want to post, and let whoever is using the service to decide what to do with the returned promise (as you do in GET method):
angular.module('starter.service')
.factory('authService', function($http) {
var service = {};
service.GetByUsername = function() {
return $http.get('/js/user.json');
}
service.PostUser = function(user) {
return $http.post("/url/to/post/user", user);
}
return service;
})
You question is not clear, but you can simply add new function to you factory service,
angular.module('starter.service')
.factory('authService', function($http) {
var service = {};
service.GetByUsername = function() {
return $http.get('/js/user.json');
}
service.PostUser = function() {
var data = {}
$http.post("/js/user.json", data).success(function(data, status) {
})
}
return service;
})
For instance this service :
services.factory('ElementsService', function () {
var currentElement = 'default element';
var service = {
getCurrentElement: function () {
return currentElement;
},
setCurrentElement: function (elmnt) {
currentElement = elmnt;
}
}
return service;
I often find useful to do the following from controllers :
controllers.controller('ElementsCtrl', function($scope, ElementsService) {
$scope.elementsService = ElementsService;
});
To be able to bind the service variables in the html and stay up to date if the variables get changed by some other controller or service. Like so :
<p>The current element is : {{elementsService.getCurrentElement()}}</p>
My question is : is this ok or should I avoid doing this?
Sure the concept is OK and saves having to make a number of different scope variables
Another way you can do it is
angular.extend($scope, ElementsService );
Then in the view you immediately have access to the same data and methods that are returned from the factory
<button ng-click="setCurrentElement(someObj)">test</button>
I am trying to create a service when I can set my formSubmit.
For example. In controller A I call "service.setFormSubmit(doThis(obj))" and in controller B I call "service.getFormSubmit()". Where it will execute the function doThis(obj) in controller B.
UPDATE - Re-formulated question.
I have 1 view where I want to edit or create a category. This means I need a dynamic ng-submit. I want to to this in the controller. So like this:
$scope.editCategory = function(obj) {
$scope.formSubmit = 'editCategory'
}
And on the create I want to change the formSubmit var to createCategory of course.
So I can make a difference between creating and editing the category.
Is this possible? Would be really nice if someone has a way to do this..!
Thanks in advance!
Instead of passing around strings which need to be eval'ed, use the service to share functionality directly between controllers.
The service can be dirt-simple:
.factory('MyService', function(){
var service = {};
return service;
});
Once injected and assigned to scope variables in both controllers you have an intermediary unit which can act as a modifiable channel for cross-controller collaboration.
.controller('FirstController', function($scope, MyService){
$scope.service = MyService;
})
.controller('SecondController', function($scope, MyService){
$scope.service = MyService;
$scope.service.create = function(obj){
console.log('Creating');
}
$scope.service.edit = function(obj){
console.log('Editing');
}
})
From the scope of FirstController, you can now call the function also available on the scope of SecondController:
<div ng-controller="FirstController">
<input type="checkbox" ng-model="button.type"> Toggle create/edit<br/>
<button ng-if="button.type" ng-click="service.create(obj)">Create</button>
<button ng-if="!button.type" ng-click="service.edit(obj)">Edit</button>
</div>
Demo
If you aren't reloading the page you can create an encapsulated variable in your service. Your set call would assign the value passed to that variable and your get call would return that variable to the caller.
One way I have achieved passing the data is to submit the form using the service and return a Json result to the service. Store the Json object in the encapsulated variable on the return and then pass a success or failure to the controller. When successful, let the controller redirect the view which will redirect using angular routing and ng-view. Once the new view, along with the new controller is loaded into the page, you can call the variable in your service to retrieve the data on the next controller.
Example Code:
app.factory('service', function ($q, $http) {
var savedData;
return {
loadData: function() {
return data;
},
search: function (parameters) {
var searchURL = '/MVCController/Search?parameter1=' + parameters.one +
'¶meter2=' + parameters.two;
var deferred = $q.defer();
$http.get(searchURL).success(function (data) {
savedData = data;
deferred.resolve(true);
}).error(function(data) {
data = 'An error occurred while searching: ' + data;
savedData = data //(if you want to save the error)
deferred.reject(data);
});
return deferred.promise;
}
}
});
What is the most simple way to share a method between 2 directives?
I've tried using a factory and injecting that in my directives. But then I can't pass parameters to the factory. So I can get data back from my factory but I can't make the factory dynamic.
.directive('myFirstDirective', [...])
.directive('seconDirective', [...])
.factory('MenuItems', [function(){
return "testString";
}]);
By adding the factory to my code I can do in any directive:
var test = MenuItems;
But what I wan't to do is:
var test = MenuItems(myParameter); //so I can change the return in menuItems depending on myParameter
You can use a service to do that:
https://gist.github.com/anonymous/50b659c72249b58c31bf
.factory('MenuItemsService', [function(){
return {
getMenuItems : function(parameter){
if ( parameter === 'foo' ){
return ['bar', 'jar', 'tar'];
} else {
return ['asd', 'bsd', 'csd'];
}
}
};
}]);
Then in each directive you can inject the service, e.g:
MenuItemsService.getMenuItems('foo');
MenuItemsService.getMenuItems('bar');
To share data creating a service is the right thing to do.
Create a function on your service to process the data
.factory('MenuItems', function(){
var someDataToShare = ...
return {
someFunction: function(data) {
// process data here
return someDataToShare
}
}
});
call it like this:
$scope.processedData = MenuItems.someFunction($scope.someData)