having trouble with dynamic segments in emberjs - javascript

This should be simple to do. I just can't pass the value of the input to the product-details view. I'm trying to create a unique template page for each item added to the list. Clicking the 'details' link should take the user to the unique page. I understand how dynamic segments works, I'm just getting stuck somewhere.
Thanks!
http://emberjs.jsbin.com/midivu/1/edit?html,js,output

In your link to helper you need to pass the parameter in...
{{#link-to 'details' name class="add-item-button"}}
Example..
If you imagine link-to as a function then in your case it would be
linkTo(route, segment, etc...)
But imagine it this way just to understand the adding parameter...
To fix your Details Route
App.DetailsRoute = Ember.Route.extend({
model: function(params) {
return userList.findBy('name', params.itemName); // assuming you want to find the details by it's name
}
});
This is because you did not create a data store. You are using a global variable as your data store, therefore, you must get it from the global.

Related

Ember: Getting model data in the controller

I am new to ember and I am building a DnD character sheet to learn and practice. Right now I am having a lot of trouble getting access to model data in a controller. After hours and hours of reading related posts it is just not clicking and I think I am misunderstanding what I am passing to the controller.
Basically what I am trying to do is grab data from a model so I can do calculations on them and then display the results of those calculations on the page.
Here is my transforms/router.js:
Router.map(function() {
this.route('characters', { path: '/'})
this.route('new', {path: 'new'});
this.route('view', {path: '/:character_id'});
});
So here I am trying to pull up the view page which has the URL of the character id. Next here is my route for the view page:
export default Route.extend({
character: function () {
return this.store.findRecord('character', id)
}
});
So this is finding the record of the character with the id I pass. My link looks like this and is coming from a component:
<h5 class="card-title">{{#link-to 'view' id}}{{name}}{{/link-to}}</h5>
Now I have my controller for the view page, which looks like this:
init(id){
let character = this.get('character')
}
When I try to log character, it is still undefined. When looking ember information in dev tools it seems the page is getting the information from the model after I refresh the page, but I just can't seem to be figure out how to grab that info in the controller itself to manipulate it.
I've been trying to figure this out for quite a while now, and its getting pretty frustrating. I currently have a work around where I do the calculations beforehand and just store all the calculated results in the model as well, but while I am learning I would like to understand how this works. Thanks is advance.
Edit: As pointed out in comments below I was missing let when defining character.
Your model hook seems wrong. You're using id but never define it. Probably what you want is more like this:
character(params) {
return this.store.findRecord('character', params.character_id);
}
Next your init hook makes no sense:
init(id){
let character = this.get('character')
}
First there is no id passed to the init hook. Second you're missing this._super(...arguments) which should always be called when you override init.
Last is that your controller is first created and later populated with the model. Also the model is populated as model property, not character.
So you could place this in your routes template and it will work:
This is character {{model.id}}
Or if you want to change something before you pass it to the template you should use a computed property in your controller:
foo: computed('model.id', function() {
return this.get('model.id') + ' is the id of the character';
}),
However for this code to run you need to use. The easiest way to use it is to put it into your template:
{{foo}}

pathFor for iron router meteor

I am pretty confused about this issue.
I have template which has two paths as follows:
Router.route('/companyDataManagement',{
path:['/companyDataManagement','/companyDataManagement/:_id'],
name: 'companyDataManagement',
yieldTemplates:{
'companyData':{to:'showCompanyData'},
'companyDetails':{to:'showCompanyDetails'}
}
});
This works perfectly fine. But how do I use pathFor for this template.
Click does not work
Can you confirm if the companyDataManagement in the link is a name being passed from a helper or if you intend this to be the name of the route called? if it is the latter it needs to be encapsulated in single quotation marks like below
Click
If you want to then pass the :_id into the pathFor this comes from the data context which the link is in, if the data context does not supply the id you need to declare an object to pass into the template inside a helper:
Template.yourTemplate.helpers({
myContextHelper: function(){
return {_id:'XXXXXXXXX'}
}
});
{{#with myContextHelper}}
Click
{{/with}}
Which should give you /companyDataManagement/XXXXXXXXX
You can also pass in the query, hash and data variables using for example query="q=1" or query=qstring where qstring is an object from a helper or a field in the myContextHelper object.
Click
Additionally and not strictly to do with the question but is hopefully helpful, it looks from your code like you are just having the :id as an optional route part in your path and that the templates themselves do not require an :_id to be specified, in which case you can just use a ? to make the part optional:
path:'/companyDataManagement/:_id?',
You can also use this for your opening argument for the route to eliminate having to specify the path in the function:
Router.route('/companyDataManagement/:_id?',{
Hope this helps! Let me know if the above doesn't work happy to help troubleshoot if you can post a bit more of the code surrounding it

Creating filters in EmberJS - Concept

I need some ideas on how to create a search filter in EmberJS where the search results can persist across views. Lets say I have a list of contacts and I filtered the list. Assume this route is called Contacts/Index
Now I have a second route called Contacts/Details. The user will be directed to this route once they select a result from the contact list. Now when they click 'Back To Contacts', I want the previous filter to be still applied instead of showing all the Contacts.
I didn't write any code yet, so I can't provide a JSFiddle. All I can think of now is probably to create a global variable to keep track of the text that is used to filter and apply that when transitioning back to the Contacts/Index view but I'm not sure if it is the right way to do it.
This is just pseudo-code that doesn't really care what your filter type is, but you could apply a filter property to the ContactsIndexController:
App.ContactsIndexController = Ember.ArrayController.extend({
//...
filter: 'name=bro',
filteredContent: function () {
if(this.get('filter')){
return this.get('content').filter//...;
} else {
return this.get('content');
}
}.property('filter')
//...//
});
Whenever you change the filter, make sure to update the filter property:
this.set('filter', 'foo=bar');
Then in your handlebars template you always loop over filteredContent:
{{#each filteredContent}}
{{/each}}
When you transition back and forth between the Contacts inner routes, it should retain the filter when you return to the index.
You can also see how this pattern could be used to take this one step further and manipulate the filter from literally anywhere in the application. If you aren't in that controller's context, you can still update that property and bindings will appropriately render the computed property next time you visit.
From another controller:
this.set('controllers.contacts-index.filter', 'year=20x6')
From a route:
this.controllerFor('contacts-index').set('filter', 'year=20x6')
From a view within the index controller:
this.set('controller.filter', 'year=20x6')
I'm sure you get the idea.
This is, of course, one of several approaches you could take. I prefer this particular pattern.
Hope that helps and good luck!

How to select option by ID from parent controller in AngularJS

Summary
What's a clean way of updating a select element in a child controller scope so that the selected item's ID matches an ID in a parent scope?
Details
I have two controllers:
OrderController
CustomerController
OrderController loads an Order and shows it on an order form.
CustomerController is the scope for a subform within the OrderController form. It shows a list of all customers, with the default customer being the one associated with the order. The user can edit the details of the selected customer or add a customer right from the subform.
Possible Solutions
I've thought of two so far, but neither seems very good.
Include a list of all customers in the JSON passed to the Order $resource. That won't work because the user needs a full separate controller to update customers on the subform.
Fire an event when the customers have loaded within CustomerController. OrderController handles that event, updating the select based on its order's customer_id property. That seems better but still hacky.
To communicate between two controllers you would usually broadcast/emit, e.g:
(Coffeescript)
CustomerController:
Api.Customer.get(
id: $scope.customer_id
).$promise.then (data) ->
$scope.$emit 'event:updateOptionId', id
OrderController:
$scope.$on 'event:updateOptionId', (event, id) ->
$scope.customer_id = id
I don't know the structure of your app but this is passing the new customer id to order controller based on an action in the customer controller. If you post some of your code you may get a more thorough answer.
I found that Angular does handle the update automatically. The problem was that my server was returning a one-item array for the order data. So the customer_id of the order property wasn't going into $scope.order.customer_id; it was going into $scope.order[0].customer_id. Correcting that on the back end solved the issue.

How to redirect to different controller?

I have an application in ASP.MVC. The requirement is that I select a person from a list of people and click 'Info' and it should load the details of the person in that page. I have the Info controller and everything works fine if I go to the Info page from a different controller. In the page I am trying to make it work with JavaScript and it doesn't seem to take me to the desired page but to a different controller.
I have a ToDoList controller and in the .cshtml I have this code on click of the Info link.
function DoInfo#(i.ToString())() {
$("#sessionid").val("#Model.cSessionId[i]");
alert("hey");
$("#PageController").val(66);
$("#formID").submit();
}
I go to the ToDoList controller to do the redirection like this
if (viewModel.PageController == 66)
{
pass = new PassingData();
pass.personid = TSSessionService.ReadPersonId(viewModel.SessionId);
TempData["pass"] = pass;
return RedirectToAction("Index", "Info");
}
It never goes there and instead goes to a different controller. I cannot seem to find how they are linked and why is it not going back to controller where the Info link button is i.e. back to the ToDoList controller.
Let me know if it is not clear and I will try to explain again and I will give any other details.
I guess I'm confused as to why you are doing this as a combination of form and JavaScript. Are there other properties that you need to pass along that you are not posting above? Why do you need to use JavaScript to do this if you are just returning a new view?
You indicate in your post that when a person is selected from a list you need to go to a controller and display a view. This seems fairly straightforward, and I would like to suggest simplifying the problem.
Start with this: change your link to not use a form or JavaScript. Just make it a link. If it is text, you can use #Html.ActionLink() and even pass in the parameters you need.
If you're not displaying text, just use #Url.ActionLink() in your href property of the anchor you're wrapping your element with. Both of these allow you to leverage routing to ensure the correct path is being constructed.
If the controller that you are trying to get to has access to whatever TSSessionService is, then you don't need to pass through the TempData["pass"] you are trying to push through, so it makes it cleaner in that way as well.
If you do need to submit a more complicated value set, I would recommend coming up with a generic .click() event handler in jQuery that can respond to any of the clicks, bound by a common class name. You can use a data-val attribute in your link and read from $(this).attr('data-val') in your handler to store/fetch other important info. This allows you to more easily build up an object to POST to a controller.
Hope this helps some, but if I'm missing a critical point then please update the question above.

Categories