i just starting to learn angular JS a month ago. And found something difficult.
I have the following plunker http://plnkr.co/edit/nsu6Pj?p=info
<input id="tags" ng-keyup="complete()" ng-model="data"/>
selected = {{data}}
As you can see, there is a list of available tags. i want to pass the selected value in the index.html page to next.html page by clicking the button.
Actually i want pass not just 1 parameter. Just like md-autocomplete in angular material.
Here is the image for example parameters i want to pass
I hope you guys can help me :) Thanks.
Well, if you're passing multiple values, you can choose to hold your values in an array or an object. I personally would just set your complete function to push the values to an array.
Now, as for exchanging data - You have three options that I can think of:
create a service that allows controllers to communicate with each other. You could then use that service to set a variable in one controller (holding your tags) and then use same service in a different controller to get the value.
broadcast an event in one controller with $rootScope.$broadcast and then listen to the event with $rootScope.$on
Save the data to the browser's cookies with angular's $cookieStore.
Now the way your stuff is actually set up you're instantiating a new module and controller in each page so options 1 and 2 are out. Here's how I set up saving the values in the cookies.
Related
I am currently trying to make a website. My main (AngularJS) controller requests JSON data, filters it and pushes it into an array. Now I would like to use said array in a different javascript file and I can't wrap my head around how to do it.
I read the option to create a service multiple times now however I believe that this is specifically for passing variables between two controllers.
Moreover, the other options did not work out for me as well.
What is the best approach to this? Thanks a lot.
You can create global javascript variable which will be accessible to both your controller as well as other JS file. Now update its value from controller which will change it at global level.
Then in the next file just retrieve it.
I'm doing some work on existing angularjs code, and I have something of that sort: I have a list of objects on the client side, which I transfer via a put request to a server side.
The existing code simply takes the list of objects in the $scope and puts it in the json as is.
I want to implement a mechanism where only the objects that have been changed since some event would be sent.
I can do that hardcodedly and save another list of objects and clear it when I submit the changes, but I want something cleaner - f.e, a Changes aware list,
Then, I could do something in the sort of list.changedObjects.
I couldn't seem to find anything like that from basic research, so I was hoping you guys would know something about it.
I feel this is a use-case of Observer pattern. https://github.com/melanke/Watch.JS has an lib/example to observe changes in javascript object. Then you can trigger an event in Angular to do your job accordingly
http://jsfiddle.net/2zT4C/23/
$watch helps to listen for $scope changes
AngularJS can then check the value returned against the value the watch function returned the last time. That way AngularJS can determine if the value has changed.
$scope.$watch('list', $scope.sendNewList, true);
it will will update innerHtml if new value of object is not equal to old value of object i.e if it has been changed.
For detailed info check this - $watch() or $watch
AngularJS watch array of objects for data change
I have an app with two controllers where I want a change in one controller to affect (different) data stored in the other. tl;dr when I remove a category from the first controller, I want to edit any items in the second controller with that category, so that they will now be category-less.
As far as I can tell what I want is to use a service, but I feel it would be simpler if there were a way for me to simply edit the data inside the controller scope. So my questions are:
Is there a way to simply edit controller data or call controller methods from a service?
Otherwise, is it reasonable to store the latter controller's data in the service, even though the former controller only needs access to change it? How do I reference this data for the purpose of doing ng-repeats?
Edit: to clarify the data is a set of json objects which contain data for each category and each item, and the web page contains ng-repeats to go through and list each of them. I have a number of functions which edit both lists of data, and I want changes to one list to make changes in the other.
Your idea was correct, you should put all your business logic, including data that needs to be consistent between different parts of your application, into services. controllers should only manage the view and connect the data to it.
Keep in mind that services are Singletons - there is always only one instance of each service, holding your data.
To answer your question: I would argue that storing data in a service instead of a controller is always reasonable when it works (aka when the data is not specific to one of multiple views, but consistent throughout the current application state), and giving access to that data to manipulate it is perfectly fine - even better would be to put the manipulation logic into the service itself (or another service only for that) and to just let the controller connect to a call invoking that.
There is an article by Todd Motto on that topic (thin controllers)
I think it will be better use events for this purpose. In your first controller you can published the event on category deletion like below.
$scope.deleteCategory = function (category) {
$rootScope.$broadcast("categoryDeleted", category);
}
Then you can observe this event in any controller like below in second controller you can listen categoryDeleted event.
$scope.$on("categoryDeleted", function (event, category) {
// do whatever you want
});
Do not call controller directly from the service, this is a bad practice, not only in AngularJS, but in most languages frameworks.
The problem you have described ("a change in one controller to affect (different) data stored in the other") is a problem of communication between components. You can solve this issue with events, thus there is no need to move data from the second controller to the service.
Let's consider some example:
http://jsfiddle.net/simpulton/XqDxG/
When you click on the LOG button the this.broadcastItem() is invoked, and the 'handleBroadcast' event is broadcasted.
Other constrollers, controllerOne and controllerTwo, handle this event:
$scope.$on('handleBroadcast'
and do the things they want to do.
So, in yor case, you can introduce the 'categoryRemoved' event, and broadcast this event in the first controller. Once the event is broadcasted, your second controller handle it and edit its items.
Also you should pass the removed category in the event (instead of 'msg' in the example), so that second controller has to aware which exactly category has been removed.
In way you want to do that, $rootScope can be used (shared across controllers - modyfing in one, accessing in another), but its generally bad idea. Im not sure if I get it right but its typical situation when you actually need service with controlling some external data.. Its some static json you want to modify? Can you specify it more clearly ? :)
I'm building an app that basically calculates prices as you pick options. So basically it's a form with select options and as you go down the form, the app will process the price more refined and change the options for the other form fields.
Currently I have an API built out and in this processing, the app will need to hit the API a few different times. There will ultimately be 7-12 form fields that will make up the pricing options. While mapping out the controllers, I'm wondering what the best method to keep my processing organized. If I was doing this in a language like PHP I'd have different functions per form element and process each time the form changes.
In Angular, having one controller per view, I'm curious how you guys, the pro, would organize it..
In a non-specific language structure I'm thinking something like...
select one has 5 options, user selects one.
Using the data from step one, a calculation happens, hits the API and gets new options for select number 2. User selects options and process happens again.
So if my controller is say...
.controller("formController", function($scope){
//Function for when select one changes, listen for form change ng-change
function item1Change(){
//hit api with item1 value, get options for item2 and and load them into item2
}
function item2Change(){
//hit api with item2 value, get options for item3 and and load them into item3
}
})
To me, this seems very dirty as in I need to define stuff, it doesn't seem modular or segmented and I just feel that there's a better option. If you guys have any better ideas, let me know, THANKS!
There is no restriction regarding the number of controller available to a view. A general best practice I have come to follow* is to initialize one controller for each $scope I feel needs to be handled with more care than that available to it's parent scope or the behavior definitons for directives within the scope.
I would use:
a formCtrl
a priceCtrl
a custom directive for the calculated total
a directive strategy for selection behaviors withing the scope paired to the form controller (one or more directives)
a service that feeds option configuraitons, dependencies, etc to your controllers and directives as needed (this is a good way to decouple your data from your controller and encapsulate the handling/processing of the data. This also makes it possible for you to provide the same data to different form views if needed
You can think of your directives and directive strategy as being similar to how you would use the decorator pattern. By decorating the form input with a particular directive, it gains the ability to __
*(this is my own best practice, I can't say it's what the Angular team or community at large endorse)
I have some fairly complicated logic in a bootstrap dialog which I've moved into its own controller for isolation.
There are times I want to launch the dialog or call a function in the controller based on some logic that occurs elsewhere in the app - in another controller, or a service. I've achieved this by adding an id to the ng-controller element then looking up the element by that id, and calling things off the .scope() of that controller. Essentially this:
In html:
<div id="modalController" ng-controller="modalController">
And in another service or controller:
angular.element("#modalController").scope().somefunction()
This seems pretty weird that I can't just get a controller by name. Is there a way to do this?
Create a service and bind the model to data maintained in that service. Make a change to the model within the service and it's made everywhere.
You could also create a service that provides a pubsub interface to the changes you need to make.
Yet another way to do it would be to have a single model representing the state of your system and modify that. Attach the relevant parts of that model to the scopes of each widget as necessary and you have a communication device built in.
It sounds like you are making a change in one place that should cause a change in another place. If that's the case, I'd argue having a service that updates all parts of the model correctly is the best way to go. Always imagine what you'd do if you added another widget that hangs off this functionality.