I have a view that contains a javascript function that i need to init/call when the page loads. The method is static but it needs to be called with some parameteres (a list of Id's) - this list is dynamic and varies by some querystring parameters (i can not generate the list clientside from the querystring).
So i need to generate this list server-side.
My options are, as far as i see it:
1) Make an ajax call on the client, requesting the ids from the server.
2) Inject/inserting the ids directly on the view (it is a property on the viewmodel).
No matter how i turn it, option 2 seems the most sane. I already got the data ready on the viewmodel and thus it's ready when the view is populated - i see no reason to make an extra request to the server, just to get the data.
I know many would think it's a bad idea to inject something dynamic into an otherwise static javascript. For that i could simply just inject a new javascript, holding only the Ids and a call to the static javascript method, which is what i really want to do.
My problem is this though: When i write my asp.net <%= %> includes, VS IDE stops highligting, making me think i might be on the wrong track? Surely i'm not the only one needing to output something in a javascript block in asp.net mvc?
Route 2 (The ViewModel) is definately the way to go and
<script type="text/javascript>
<%= Model.JavascriptToInsert %>
</script>
should work (despite lack of VS highlighting)
It will NOT work in a seperate JS file though. It must be in your view itself.
Kindness,
Dan
Related
I'm using MVC5 and passing model from Controller to View. In the view I have
var test = #Html.Raw(Json.Encode(Model.Data));
It work great, I have my model in the js variable. The problem is when I'm going to see my HTML code, the whole variable is rendered
Is there any way how I can remove or hide this code?
Thanks
To pass a variable from your server to the client you have two options really:
Do what you have done (but the value is rendered in markup)
Expose a webapi and query the endpoint in javascript to get the data
Option 2 is best practice.
Without more details on what you're trying to achieve I can't give a more detailed answer, but basically you should be looking into webapi to resolve this.
note: there are other things you could do like websockets and cookies, but it's unlikely that you want that kind of stuff for this
After reading David Heinemeier Hansson's blog post about server-generated javascript I decided to review the way I approach making AJAX calls in my Rails applications. What David suggests is to create a .js.erb template, which is just javascript embedded with ruby code generated on the server, and not to do any DOM manipulation in the client-side javascript.
Another approach is of course to simply do everything on the client-side, and (for example) return a JSON object representing the updated object from the server and use javascript to do all DOM manipulation.
I dislike the first approach for two reasons:
1) I use HAML and Coffeescript in my application, and feel that by using vanilla javascript and ERB would uncecessarily bloat my code-base with code of a different language (maybe it's possible to create .coffee.haml templates rather than js.erb, I don't know)
2) I really don't like the idea of 'littering' my view folder with what is essentially javascript files, with a little bit of ruby embedded.
The second approach, as David talks about in his blog post, relies very heavily on client-side javascript, which could lead to bloated client-side javascript code, and possibly the need for client-side templates, which in worst case scenarios could mean almost doubling the number of templates.
The approach I decided to go for (and want to ask whether or not is completely stupid way to go about this) is the following:
1) Set the remote: true flag to make links and forms utilize AJAX to post to the server.
2) In my controller, handle everything as html, and simply render without layout should the request be an AJAX request: render partial: '<partial-name>', layout: false if request.xhr?. This simply returns the HTML of the partial, with the ruby code evaluated.
3) In an asset javascript file (for instance <partial-name>.js.coffee) listen to ajax:success and append the HTML from the response.
I like this approach because (in my rather simple application) this allows me to keep all my code in HAML/Coffeescript, and avoids any javascript templates.
I realize this problem might take on a different character should the complexity of the application grow, but I still feel that it's a valid question: is this a bad way to go about implementing an AJAX-based architecture for a Rails application (and if so, why? i.e. is there a reason why returning HTML instead of JSON from an AJAX call is a bad idea?) or is this something I should continue to utilize?
Thank you :-)
Your approach seems to me quite accurate. However I would change 1 pt. Instead of using remote: true, I would use jQuery ajax call directly.
$(function(){
$('#some_link').click(function() {
$.ajax({
// some parameters here
})
.done(function(data){
$('div').html(data);
});
});
});
if you use remote: true it sends a js request instead of html request.
then when the controller method is executed, it looks for the js.erb or js.haml file which has the same name as the controller action that just finished executing.
in this file you can write 'js' code to perform any action that needs to be done after the controller action has completed executing like changing a partial or updating view, etc.
if you have a function in javascript asset file, you can call that function as well.
I am new with MVC. I found this site is very helpful. But I've been struggling with the Model data accessing from Javascript. Here is my question.
I know if I controller return a single item, then I can use <%: Model.Name%> in <script> section.
But for the case where there are more items in Model, <%foreach (var item in Model) %> would not work in <script> even it works in other part of the view.
Can somebody shed me some light on this?
Also could somebody recommend a good book on MVC, and Razor?
It would be helpful to know more about your Model class. Most likely, you have a class with some kind of collection:
public class CollegeCourse
{
public string Professor {get;set;};
public List<Student> Students {get;set;};
}
You can loop through this collection in your server-side code like this:
<% foreach (var student in Model.Students) %>
As far as JavaScript... The example you gave is an example of how you would loop through your List<T> and build some HTML on the server side. But by the time your page loads in the browser, that model data is long gone.
To interact with model data from JavaScript, you need to choose a strategy for getting the data to the browser. A few ideas:
Transform your data to JSON on when your page loads, then write it out in <script> tags.
Embed your data in HTML tags, perhaps by using data- attributes. Then you can use jQuery to retrieve the values.
Add an action to your controller that returns the data you need as JSON. Then, after your page loads, you can use a jQuery AJAX call to retrieve the model data and do whatever magic you plan to do with it.
The first two options aren't really considered good practices. I'd recommend that you look into the AJAX approach. Here's a quick example that shows how you might be able to do this. It's not too difficult, and MVC3 even has some built-in helpers to make setting up the AJAX call simpler.
If you're generally comforable with ASP.NET, then Professional ASP.NET MVC3 is an excellent book to get your head around MVC and Razor.
I have a page when user can add 0 to N TinyMCE editors that need to have some div soup around it.
I have the html code in a gsp _template because it is more then a few lines and I didn't want to stuff it in javascript. Basicaly everytime user clicks "add editor", an ajax call is made to the server with new id as the only parameter, controller renders the template with elements properly named using the new id, and it is appended by javascript to the page.
I think its a pretty elegant solution, but what bothers me are the ajax calls that are fired for every new editor that is to be added to the page which has always the same code apart from different element id's.
Will this have any performance impact? Is the template cached after first call?
Thanks
The GSP should be compiled (pre-compiled on grails war) and then there is some caching to help speed up GSP rendering. The performance issues are no different than considering any amount of traffic. The server doesn't care (or know) that the request is Ajax. It is just responding to a request. IF you remove ajax from your equation and just look at it that way, would you still be asking the performance question?
That said, if all you need is an ID attached to the elements in the template, I might look into something like a javascript template solution (jquery.template() for example). That would negate the call to the server entirely.
A psuedo controller method
#RequestMapping("/foo")
public String getFoo(Model model) {
model.add("foo", repo.findFoo());
model.add("bar", repo.findBar());
model.add("barOptions", repo.findBarOptions(bar));
return "fooView";
}
Let's say the client uses Expression language to render foo and bar; but we use JavaScript to render barOptions.
<html>
<script>
var options = <mytag:toJSON object="${barOptions}"/>;
$("#options").renderOptions( options );
</script>
<body>
<mytag:renderFoo foo="${foo}"/>
<mytag:renderBar foo="${bar}"/>
<ul id="options"></ul>
</body>
</html>
Common conventions tells me this is bad. But the essence of MVC, where the controller sends data and the view determines how to use it, tells me this is good. Is there a better way to do the same thing? Is there any reason why this isn't commonly done? I could request the JSON using a separate call, but then I have to make more requests for the page to load, and there may be logic to determine barOptions in the controller method getFoo() based on other input at the time of the page load.
At first glance I can not say that I see anything blatantly wrong with approach. The only aspect that initially took me off guard was your need to convert data in the model object to json.
For me, JSON usually implies that there is some sort of server side object that needs to be converted so that a client side javascript can access or manipulate its structure in a javascript way. I guess without knowing more of the purpose of the options list, I can't see a reason why json serialization is required here.
By using a Tag to convert a model object to JSON, we avoid an
additional request made by the client
But if we assume that JSON is a requirement (perhaps for some third party jquery plugin), then I absolutely do not see anything wrong with approach.
What is special or different about the barOptions unordered list, why does it have be rendered with json? Why not just use a for loop to build the list items? Or you can have a custom tag that builds out the ul entirely.
Aside from that, I missing the point as how one may perceive this as being bad code.
Normally JSON is requested by JavaScript with an Ajax call, but if in your case it's available at page rendering time, I see nothing wrong with your solution. It's clean, compact code and easy to read. Looks perfectly OK to me, the alternative would be to loop on the options array with a forEach, but this approach looks better.