pathFor for iron router meteor - javascript

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

Related

Where to put a particular template helper

I have a pageTitle template variable that is in the header element () of each section of my site, and I would like it to be dynamic, rather than hard-coded, so site maintenance is easier.
Using Meteor (I'm currently reading Discover Meteor), would it be best to put it in a Session variable, and then return the value from a Template helper (i.e. as in the example in the Session chapter of Discover Meteor), or is there an Atmosphere package that would handle this better?
Also, if I do put it in a Template helper, I'm a little fuzzy about where is the appropriate file in which to put the helper. That is, if I have a .js file for (almost) every template (because I'm following along with the book), would I really need to put the same helper code that returns the pageTitle variable from the Session in each template's .js file?
It seems inefficient to have so many redundancies, but if I had a single instance of that Template.templateName.helper() code, I'm not sure where to put it.
Any help is much appreciated. Thanks!
I'd put it inside a global helper. You can use Template.registerHelper for that. I usually put these helpers inside client/helpers/global.js. I'm not sure why you would want to use a session variable for this. But here's a simple example of how this helper could look like:
client/helpers/global.js
Template.registerHelper('setPageTitle', function (newTitle) {
document.title = newTitle
})
Usage:
{{ setPageTitle 'Hi' }}
I'm also fairly new to Meteor, but it looks like you could use the Observe Collection from the docs - http://docs.meteor.com/#/full/observe and have a collection with your pageTitles in it.
So it would be something like
document.title = yourCursor.observe(function({
changed: function(id, field){return field.pageTitle}
})
As for location, anywhere on the client side should work.
Not sure if this is best way to do it, but hope it helps!

having trouble with dynamic segments in emberjs

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.

Get controller not working with Ember.textfield

App.PhotoUpload = Ember.TextField.extend
type: "file"
change: (evt) ->
# #get('controller') gives - App.PhotoUpload
#get('controller').send('uploadImage')
In above code,if I debug it and check #get('controller').constructor it returns App.PhotoUpload, which is not right and it doesn't call uploadImage action which is in my route.
When I change Ember.TextField to Ember.View, #get('controller') works as expected and uploadImage action is called. But, as Im doing auto update to server on image upload, I need to stick with TextField.
I have these questions:
1. What are ways to access another controller from Emberview ?
2. How can I get access to right controller from Ember.TextField ??
The problem here is that the included input fields were recently modified to extend Ember.Component instead of Ember.View. One of the primary differences between a component and a view is that the controller property of a component is itself. Honestly, I'm not totally sure why that change was made. Having said that, it's still possible to access the controller from the context of where the text field was defined using the targetObject property.
Update:
I looked into this a bit more and it turns out that not all input fields were turned into components, only the TextField and TextArea. It appears the primary reason for turning them into components was to expose some helpful action handlers since components provide that capability.

Where does data returned by ember-data 'live'?

ya'll I have a bit of a structural/procedural question for ya.
So I have a pretty simple ember app, trying to use ember-data and I'm just not sure if I'm 'doing it right'. So the user hits my index template, I grab their location coordinates and encode a hash of it (that part works). Then on my server I have a db that stores 'tiles' named after there hash'd coords (if i hit my #/tiles/H1A2S3H4E5D route I get back properly formatted JSON).
What I would like to happen next, if to display each of the returned tiles to the user on the bottom of the first page (like in a partial maybe? if handlebars does that).
I have a DS.Model for the tiles, if I hard code the Hash'd cords into a App.find(H1A2S3H4E5D); I can see my server properly responding to the query. However, I cannot seem to be able to figure out how to access the returned JSON object, or how to display it to the user.
I did watch a few tutorial videos but they all seem to be outdated with the old router.
Mainly I would like to know:
1. Where does the information returned by App.find(); live & how to access it?
2. what is the 'correct' way to structure my templates/views to handle this?
3. how should I pass that id (the hash'd coords) to App.find? as a global variable? or is there a better way?
the biggest problem(to me) seems to be that the id I search by doesn't exist until the user hit the page tho first time. (since its dynamically generated) so I can't just grab it when the page loads.
I can post a fiddle if required, but I'm looking for more of a conceptual/instructional answer rather then some one to just write my code for me
I'm still learning a lot with Ember as well, but this is my understanding. When you follow the guides and the tutorials out there, you'll have something like this:
App.TileController = Ember.ObjectController.extend();
App.TileRoute = Ember.Route.extend({
setupController: function(controller) {
controller.set('content', App.Tile.find(MYHASH));
}
});
What it does is set the special content object to the result. So since we're declaring an object controller, and calling find with a parameter, it knows that a single result is expected. So a view & template that follow the naming convention of Tile will be loaded. And in there you can access properties on the Tile object:
<p>{{lat}}</p><p>{{lng}}</p>
I have to admit that this feels a bit mystical at times. The core to it is all in the naming convention. You need to be pretty specific in how you name all your various controllers, routes, etc. Once that's nailed down, it's a matter of binding what data you want to the controller's content.
1) Aside from the generic answer of "in memory", the .find() calls live where ever you return it to. Generally speaking, this is meant to be set on a 'content' property of a controller.
2) I more or less answered this, but generally speaking you take the name of your route, and base it off that. So for a route TileRoute, you have:
TileController = Ember.ObjectController.extend
Tile = DS.Model.extend
TileView = Ember.View.extend
tile.handlebars
I generally store all my handlebars files in a templates/ folder. If you nest them deeper, just specify the path in your view object:
App.TileView = Ember.View.extend({
templateName: "tiles/show"
});
3) This really depends on your app. Generally speaking its better for the id to be either obtained from the URL, or constructed locally in a function. Since you are encoding a hash, i imagine you're doing this in a function, and then calling find. I do something a bit similar for an Array controller.
I don't know at what point you are generating a hash, so let's say it's onload. You should be able to generate the hash just in the setupController function.
App.TileRoute = Ember.Route.extend({
generateHashBasedOnCoords: function() {
// ...
},
setupController: function(controller) {
var MYHASH = this.generateHashBasedOnCoords();
controller.set('content', App.Tile.find(MYHASH));
}
});
I hope that helps.
I believe that you can make use of the data binding in ember and basically have an array controller for tiles and set the content initially to an empty array. Then we you get back your response do a App.find() and set the content of the tiles controller with the data that is returned. This should update the view through the data binding. (Very high level response)
The data itself is stored in a store that is setup with ember data. You access it with the same method you are using the model methods App.Tile.find() ect. It checks to see if the data that is needed is in the store if so it returns the data otherwise it makes a call to the api to get the data.

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