Angular UI Router: Dedicated UI-View - angular-ui-router

I am wondering if it is possible to have two ui-views one one site: both are child of the parent state. I want first ui-view to be dedicated to the first child, and second to the second one. Any ideas?

I'm not sure I entirely understand the question, but ui-views can be nested in any way to form a tree structure. This is done using the dot notation for states.
state1.state2
state1.state3
http://angular-ui.github.io/ui-router/site/#/api/ui.router.state.directive:ui-view
If you want to keep two views within the same state, you can use the ui-view name attribute to handle that. The linked page explains how toward the bottom.
From the linked page:
Really though, you'll use views to set up multiple views:
<div ui-view></div>
<div ui-view="chart"></div>
<div ui-view="data"></div>
And the JS:
$stateProvider.state("home", {
views: {
"": {
template: "<h1>HELLO!</h1>"
},
"chart": {
template: "<chart_thing/>"
},
"data": {
template: "<data_thing/>"
}
}
})
It's also worth mentioning that each view object here can have its own controller.
Information from comment stream:
The answer is no, there's no way to have two ui-views for separate sub-states. You would have to create one ui-view with two separate states under it, which would still only allow one to be shown at a time. I really think you're looking for two views in the same state, but without an example all I can do is guess.

Related

Assembling N-Nested Kendo UI Grid asp.NET MVC 4

I am looking for N level nested child behavior in Kendo UI grid.
so far i have been implementing upto 3-4 level but those grids have to be hard coded in the Code.
Please Guide if somebody has done it dynamic way or generating grid dynamically as child grid
if Possible any alternatives to achieve same.
I hope you guys can help out.
I have edited the Detail Template demo found here: http://demos.telerik.com/kendo-ui/grid/detailtemplate
The fiddle:
http://jsfiddle.net/j5b64/1/
detailRow.find(".orders").kendoGrid({
detailTemplate: kendo.template($("#template").html()),
detailInit: detailInit,
dataSource: {...
Detail rows are not initialized until they are expanded (They don't exist in the DOM). So the call to make the new grid can't happen until we expand the row that will contain it.
Luckily Kendo had provided a 'detailInit' Event that you can plug into and initialize your child grid.
Update for .net binding:
First on your page you will need to define a template. It is important to use a class and not an ID in your template. Your template will be used multiple times and you want to maintain the uniqueness of IDs.
<script type="text/x-kendo-template" id="template">
<div class="orders"></div>
</script>
You will then need to reference that template to be the detail row template for your grid. Here we just need to reference the id of our template above. (you can use .DetailTemplate() to define the template in line, but then it would be harder to use it for later child grids as you would have to parse it out of the server made JS)
#(Html.Kendo().Grid<mySite.ViewModels.GridViewModel>()
.Name("Grid")
.ClientDetailTemplateId("template")
.Columns(columns => .....
Now comes the JS. There is two things we need to do. One is create a reusable initiation function and the other is register this function to be ran on initiation.
In our function we should define a new grid. Again this is done in JS at this point. Theoretically you could define an example grid and look for the server built JQuery that would be its sibling and reuse that for your child grids, but at that point you might as well define your grid using JQuery.
function detailInit(e) {
var detailRow = e.detailRow;
detailRow.find(".orders").kendoGrid({
detailTemplate: kendo.template($("#template").html()),
detailInit: detailInit,
....
Now we need to link up our first grid to use our Initiation function
$(document).ready({
$("#Grid").data("kendoGrid").bind("detailInit", detailInit);
});
I hope this helps.

Update template inside a view rendered from another controller

I am looking for the way to refresh a template inside a view rendered from another controller than the template's controller, I mean:
I got two controllers AdminController & UserController. And two gsps /admin/listUsers & /user/_searchResult.
Then a want to render view listUsers who have inside the template _searchResult and all right.
Now, i want to refresh the template _searchResult, but cant find how. I tryed calling render(view:"/admin/listUsers", template:"/user/_searchResult", model:[searchResult:result])
AdminController.groovy
#Secured(['ROLE_ADMIN'])
def listUsers(){
//...
}
UserController.groovy
#Secured(['ROLE_ADMIN'])
def search(){
//search users for the givven params and send result by chain if there's an action or update a template if it's needed
//in my case this method need to update the template _searchResult
}
#Secured(['ROLE_ADMIN'])
def searchResult(){
//...
[searchResult:result]
}
listUsers.gsp
//...
<formRemote name="searchForm" url="[action:"search", controller:"user"]">
//Some fields for the search
//I need to place here some hidden inputs to send which
//template i want to update or action to redirect
</formRemote>
<g:render template="/user/_searchResult"/>
//...
_searchResult.gsp
//Just itterate and print the search result in a table
I hope I have explained the problem correctly, thanks!
I don't think I entirely understand your question, but I think the source of your confusion is that the way you are naming things doesn't follow regular conventions and you're not using the right tools for the job. Let me explain...
The methods on Controllers are called Actions. They send some data (the Model) to a View to be rendered into HTML. Views can be composed from smaller, reusable fragments called Templates. (sorry if I sound like I'm being condescending here, but I'm just trying to make sure we're all on the same page).
Now, what you've called templateA is actually a View, not a Template. You're correct that templateA (your View) can call templateB to render some markup, but then having the templateB try to call a method on another Controller doesn't make sense. That's not how things flow.
If you have some logic that needs to be executed after you've sent your Model to the View, you want to use a Tag Library (http://grails.org/doc/latest/guide/theWebLayer.html#taglibs).
To summarise, here's a quick recap.
A request should only call one Action, which sends the model to only one view.
If you need to reuse logic between Controllers, move that code to a Service.
If you need to reuse markup between Views, move that markup to a Template.
If you have logic that you want to have executed after you've sent the Model to the View, use a Tag Library.
Hopefully this will point you in the right direction.
--- UPDATE ---
OK, with the real code I can see better what you're trying to achieve. Firstly, as you're using the <g:formRemote> tag, you should have a good read of the docs at http://grails.org/doc/latest/ref/Tags/formRemote.html to understand what it does.
What you will have here is 2 separate requests. The first will be a regular page load by your browser, which is handled by the listUsers() action. Once the page is then finished loading, the user will enter a search term and hit the submit button. This will fire off a second ajax request, which will be handled by the search() action. This action could use the _searchResult.gsp template to render a HTML table to display the search results. When the browser get this, it will insert it into the DOM where you've told it to put it using the "update" attribute of the <g:formRemote> tag.
The important thing here is that from the server's perspective, these are 2 separate requests that are completely independent. They both first call an action, then send a model (a Map containing some data) to a view, which renders/merges the data with HTML and sends it back to the browser.
The difference between the 2 is that the first is a complete page load by the browser, whereas for the second request, the browser only loads a small chunk of HTML (the search results table) and updates the page content without reloading it.
So your code would look more like this...
AdminController.groovy
#Secured(['ROLE_ADMIN'])
def listUsers() {
render(view:"/admin/listUsers")
}
listUsers.gsp
<g:formRemote name="searchForm" update="insertSearchResultsHere"
url="[controller: 'user', action:'search']">
<input name="searchTerm" type="text" />
</g:formRemote>
<div id="insertSearchResultsHere"></div>
UserController.groovy
#Secured(['ROLE_ADMIN'])
def search() {
// use the search term to get a List<User>
render(template: "/user/searchResult", model: [users: users])
}
_searchResult.gsp
<table>
<g:each var="user" in="${users}">
%{-- Iterate through your search results --}%
</g:each>
</table>
I solved it by placing the attribute update and rendering the template alone:
gsp:
<formRemote name="searchForm" url="[action:"search", controller:"user"]" update="divToUpdate">
//Some fields for the search
</formRemote>
<div id="divToUpdate">
<g:render template="/user/_searchResult"/>
</div>
Controller:
def search(){
render(template:"/user/_searchResult", model:[searchResult:result])
}
When i asked this question, i was new on Grails community and i was confused with the use of remoteFunction and tags that use it like remoteForm. But i had this confusion because of i had not read the documentation. So in my case, the solution was search for documentation about how to use remote tags and render. Thanks to #AndrewW for show me the way.

How to I add multiple distinct JSON objects into seperate lists in WinJS app?

I am trying to create a grid app with various sections and each section is being fetched to a specific listview however I have encountered a problem where you can only have one listview covering the entire page in order to properly horizontally scroll the objects inside the list which means there's no room for another one. This is the code I am using right now:
WinJS.xhr({ url: "http://search.twitter.com/search.json?q=%23windows8&rpp=100}).then(
function (response) {
var json = JSON.parse(response.responseText.toString());
var list = new WinJS.Binding.List(json.result);
gridView1.winControl.itemDataSource = list.dataSource;
//gridView1 is ID of listview
}
With the above code I can easily show grids of objects containing result array and then bind em to the list. However now I want multiple similar listviews for different URLs that are displayed like the one shown as default interface in WinJS grid app.
To be more clear, this is what I want - Twitter usernames in first section of grid by using Twitter API URL1 and then I want twitter search results in adjacent grid so I have to use another listview b using URL2.
How do I find a fix for this. Appreciate your help.
Yeah, coming up with what all of the disparate items from the different lists have in common and projecting your data up to a single grouped list is one option. You might not want to give up on what you were trying to do though. If you put multiple ListViews on a page wrapped in a flexbox, you shouldn't have any trouble with scrolling. If you look at my codeSHOW app at the ListView demo, you'll see that I have the rough equivalent. Windows is actually really smart about the way it handles the panning.
** EDIT **
Here's a rough example of what I'm talking about. Again, you can find a working example of this in the ListView demo of codeSHOW.
<!-- HTML snippet -->
<div class="hub">
<div>
<div id="list1" data-win-control="WinJS.UI.ListView"></div>
</div>
<div>
<div id="list2" data-win-control="WinJS.UI.ListView"></div>
</div>
<div>
<div id="list3" data-win-control="WinJS.UI.ListView"></div>
</div>
</div>
/* CSS snippet */
.hub {
display:-ms-flexbox; /* this will lay the lists out horizontally */
overflow-x:auto; /* set the flexbox to scroll its overflow */
}
/* select each of the sections */
.hub > div {
padding-right:80px; /* 80px of space between "sections" */
}
/* choose whatever sizes you want for your list views. You may want to make them wide
enough that they don't scroll because it can get a little awkward to have scrolling
within scrolling */
[data-win-control=WinJS.UI.ListView] {
width: 640px;
height: 480px;
}
You can solve this by aggregating the result set into a single data source.
You can either do this through splurging your data into a WinJS.Binding.List that's been set up with a grouping function, and attribute your data in such a way that you know how to group them. An example of the grouping of a WinJS.Binding.List can be found in the "Grid" Template that you find in Visual Studio when doing File/New/Project.
Or, you can build your own data VirtualizedDataSource - there is a great tutorial for this on MSDN here.

Performance issue in backbone template

I am having a performance issue with backbone template.
The situation is I have collection of model, each model have a field called 'isSelected'.
I need to render this collection with a template for each individual model. The 'isSelected' field is used for setting the checkbox in the template.
For the sake of discussion, the template is as following.
<div class='thumbnail'>
<input class='checkbox' type='checkbox' {[ if (isSelected) { ]} checked='checked'{[ } ]}
</div>
When I need to make the checkbox all selected, I will update the field to true for each model in the collection.
The code I used is
this.collection.each(function(e) {
e.set("isSelected", true);
});
However, this way is very slow, for a collection contains 25 items, it will take almost 10 sec to make all checkbox 'checked'.
I am expecting that it should least than 1 sec, if i use plain jquery.
Is there any problems with this approach? what's the best approach for this kind problem?
Why don't you set isSelected to true as default in the model? That way you don't have to loop through the collection to set each of them to true.
It's hard to tell what's taking up all the processing time with the amount of code you posted. My first guess would be the render function is being called multiple times. Creating and destroying templates kills performance. If you hard more code posted it might be easy to spot any problem areas.
You should render all of the HTML nodes that could possibility be need. After they are rendered save a jquery selector and use that to toggle the selected.
Most of the time it isn't JS or Backbone that is the bottleneck. It's that JavaScript is triggering the DOM, CSS or reflows constituently and the browser is doing way too much work.
I'm building a PerfView for for backbone. It can render a collection with 1,000,000 models and scroll at 120FPS on chrome. The code is on Github at: https://github.com/puppybits/BackboneJS-PerfView. There's a lot of optimizations in there and comments in the code. One of the techniques in there is sure to solve your issue.

MVC3 write to #rendersection more than once

How do I write to:
#RenderSection("Top", false)
more then one time from a partialview?
You can't, directly.
Your content page could itself contain a #RenderSection() call, but I'm not sure that's what you mean.
Alternatively, if you want to write to different content areas, you can simply make multiple calls to #RenderSection(), and match the sections by name in your views.
Inside the partial View:
#section Top{
#: Hi from partial!
}
Inside the View:
#section Top{
#RenderSection("Top", false)
}
Inside Layout:
#RenderSection("Top", false)
This is how you access the section from inside the partial view. You can't call it more than once though, and it doesn't make sense to have to write many times to it.
If you find that your partial view needs to write at "Top", then suddenly it needs to write at the "Bottom", you have a bad design and you need to rethink your views/controllers

Resources