UI Router: passing Parameters into ui-view - javascript

The UI Router manages states for AngularJS applications and supports nested views as well as multiple named views for the same state.
Multiple named views are used like this:
<body>
<div ui-view="viewA"></div>
<div ui-view="viewB"></div>
</body>
You can also pass URL-parameters into states when navigating between states via ui-sref (Check this question: Angular ui-router - how to access parameters in nested, named view, passed from the parent template?).
Q: Is it possible to pass parameters to a named view using ui-view which then is propagated to the according state?
Q: How do i pass parameters if i switch between states by using $state.go(newState)?
A:
$state.go(newState, { Param: 123 });

The $state.go(newState, { Param: 123 }) suggested in the comments is definitely valid.
I tried using another method and it worked as well.In the main app.js file where I have defined my states, I defined a variable var myData={}; outside the module definition(but in the JS file) . Think of this as a global data variable of sorts.
In the controller for viewA you can set a variable by setting
myData.somevalue=$scope.valueFromViewA;
You can access this value in viewB by something like
$scope.valueInB=myData.somevalue
As I said, this is one way of doing it, services is another and the methods in the comment are valid too.

Related

get access to variable in directive from controller

I created a directive, I´m using in my template:
<data-input> </data-input>
In my directive (dataInput) I have the template (...data-input.html).
In that template the html-code says:
<input ng-change="dataChanged()" ... > ...
In the JavaScript it says:
scope.dataChanged= function(){ //change the data }
Works perfectly, but know I need to safe the changed data to a variable in my controller (that has a different scope of course).
The template, where I put the <data-input> </data-input> belongs to the final scope, I´m trying to reach.
I tried it via parameter, but it didnt work.
Thanks
Here are your options:
You can nest controllers if possible. This will create scope inheritance and you will be able to share variables of the parent.
You can use $rootscope from both the controllers to share data. Your dataChanged function can save anything to the $rootscope
You can use angular.element to get the scope of any element. angular.element('data-input').scope() returns it's cope.
This is not recommended. But there are circumstances in which people use global space to communicate between angular and non-angular code. But I don't think this is your case.
You can use Angular Watches to see changes is some variable, like this
eg:
$scope.$watch('age + name', function () {
//called when variables 'name' or 'age' changed
//Or you can use just 'age'
});

How to manage ui-router or share $scope in different $state

I have an AngularJS site, the object-resource I want to show is:
each user has a basic account, that will show in a single page (named basic-page);
user has several sub-account, each sub-account will show in a diffent page (named app-page);
basic-page will show the summer info about the sub-account, so app-page can share the loaded $http data of basic-page is better for code reusing.
As the purpose, I use ui-router define state below:
.state('user', {
url: '/user/{id}',
title: 'User-Page',
templateUrl: helper.basepath('user.html')
})
.state('user.app', {
url: '/{app}',
title: 'App-Page',
emplateUrl: helper.basepath('app.html')
})
Notice that state user.app is the child of user.
What I want is when I enter the user.app, it can reuse the data in user, ecen if it's a different page, that the user need not to contain a ui-view to include user.app's template.
But actually I enter user.app, and it doesn't show the app.html(because I didn't include ui-view in user.html).
Maybe this is not the correct usage of ui-router.
So, how can I share data in different $state? Anyone can give me a detailed example? Thank you.
Sharing data across controllers
Any time you need to share data across states you will need to create a service/factory that you can instantiate in your controllers associated with those states.
The factory will consist of basic getters and setter for the different data you need to share. Just like when you build getters and setters in java to share across classes.
Example Code
.factory('yourFactory', function ($scope) {
return {
get: function () {
return $scope.someValue;
},
set: function(value){
$scope.someValue = value;
}
};
})
Disclaimer: I've not tested this code but it should do the job for getting and setting some values you need to access across your app.
Demo : Working plunker with this approach.
Alternative: 1
This is the "Dirty" alternative, you can set a global variable with $rootScope. It will be accessible everywhere since its global, I strongly advise you don't do this but though I would point it out to you anyway.
Alternative: 2
When a state is "active"—all of its ancestor states are implicitly active as well.So you can build your states considering the parent-child relationship and share data across scopes in hierarchical manner.
Official Docs and working plunker with mentioned approach.

modify a property of a component through a controller in emberJS

I wonder if I can modify a property that is in a component via an external controller.
That is, I have an injected component in index.html as follows:
{{ button-feed }}
This component is used in many views.
This component has to be hidden as I get values in the controller, and what I really want is that since this controller, modify a property that hides or shows the button.
The component has the form:
App.ButtonComponent = Ember.Component.extend ({
   hideClass: false
});
The property hideClass is used to display or not the button. What I want is to modify this property but using a controller that does not belong to the component button.
I tried to access the property from outside the component, but it is impossible.
You can pass parameters to your component like this:
{{button-feed hideClass=true}}
{{button-feed hideClass=false}}
Also, you could pass in a controller property too.
{{button-feed hideClass=controllerProperty}}
To answer your comment, you can set the controllerProperty by using the code below. Since controllerProperty is bound to the hideClass on your component, changing controllerProperty will change hideClass.
controller.set('controllerProperty', false);
You can read more about setting properties on a controller here.

Angular ui-router: Can you change state without changing URL?

The multiple nested views functionality of the ui-router is very nice - you can easily jump from one state of your app to another.
Sometimes you might want to change the URL, but sometimes not. I feel like the concept of state should be separate/optional from routing.
Here's a plunker that shows what I mean. This is a fork of one of the plunkers in the ui-router documentation, with 2 minor changes noted below:
.state('route1', {
url: "/route", // <---- URL IS SHARED WITH ROUTE2
views: {
"viewA": {
template: "route1.viewA"
},
"viewB": {
template: "route1.viewB"
}
}
})
.state('route2', {
url: "/route", // <---- URL IS SHARED WITH ROUTE1
views: {
"viewA": {
template: "route2.viewA"
},
"viewB": {
template: "route2.viewB"
}
}
})
This seems to work - the URL stays the same. Again, how much redundant work is done here? Is this an approved/tested usage?
It would be nice if you could omit the url from a state..
UPDATE: You can omit a url from a state. plunker
Update question: Is this an approved/tested usage?
You can absolutely have a state without a URL. In fact, none of your states need URLs. That's a core part of the design. Having said that, I wouldn't do what you did above.
If you want two states to have the same URL, create an abstract parent state, assign a URL to it, and make the two states children of it (with no URL for either one).
To add to the other answer, Multiple Named Views do not use a URL.
From the docs:
If you define a views object, your state's templateUrl, template and
templateProvider will be ignored. So in the case that you need a
parent layout of these views, you can define an abstract state that
contains a template, and a child state under the layout state that
contains the 'views' object.
The reason for using named views is so that you can have more than one ui-view per template or in other words multiple views inside a single state. This way,
you can change the parts of your site using your routing even if the URL does not change and you can also reuse data in different templates because it's a
component with it's own controller and view.
See Angular Routing using ui-router for an in-depth explanation with examples.

Ember: transition to route passing the ID instead of obj

I have some route like /ads/:ad_id and from my controller I can do
this.transitionToRoute('ads.ad', adObj)
How can I do the similar thing but this time passing the ID instead of the loaded object?
O course I understand that I can load an obj by ID first, but Ember's power is in doing lost of boilerplate for us.
Update: So, as by default Ember serializes the model to URL params by doing like
mode_instance -> { model_name_id: model_instance.id }
My trivial attempt was doing
this.transitionToRoute('ads.ad', { id: adObjId })
But when passed a model object Ember does not re-fetch it.
So, the question: I have a route (single ad view) that depends on ad ID. I have this ID as number. I want to transition to this route like if I simply entered the url /ads/ID
This can be accomplish by passing the URL to transitionTo. For example,
this.transitionToRoute('/ads/' + adObjId)
The model() method will be called with the params from the URL.
Here is a use case for this:
Transitioning from a list view to a detail view. In the list view, the records don't have any relations tied to them, but the detailed view should side-load relational data. For this reason, the models are not 1:1 between the list view and detailed view. There should be a way to transition simply using the id.
Cp
What's your use case for this? Most cases when you would want to specify an object by id, you already have the object to pass to transitionTo. Can you provide more context about what you're trying to do? I think you can probably accomplish it without using the object id.
In any case, I don't think there's a good way to do this, because when you transition via transitionTo(someRoute, someModel), the route's model hook is not called, and the model you pass in (someModel) is supplied directly to the other route hooks (setupController(controller, model), redirect(model), renderTemplate(controller, model)).
See Ember.JS Route api -- model method for more details.

Categories

Resources