I created a RazorViewEngine subclass to redefine where it looks for views.
I set PartialViewLocationFormats string array to contain values
"~/Views/{1}/{0}.cshtml",
"~/Views/{1}/Partial/{0}.cshtml",
"~/Views/Shared/{0}.cshtml",
The first and last are there by default. The 2nd one is the one I added, so that I could have a "Partial" subfolder in each "Views/ControllerName" folder for partial views used only by views within that controller, rather than adding them to the "Views/Shared" folder.
The issue I'm encountering is that calling #Html.Partial("_TopNavbar") is finding and rendering the '_TopNavbar.cshtml" file that's in the "Views/Shared" folder, rather than in the one under my DashBoards's "Views/Dashboard/Partial" folder.
In other words, there are two different files named "_TopNavbar.cshtml" in two different folders, and I'm expecting it to be found in one location because it's more specific and occurs first in the array, but it's not working that way for some reason I don't understand.
The Partial call is inside "Views/Dashboard/Index.cshtml', and I'm accessing it by directly navigating to "localhost:port/Dashboard/Index", so I'm sure the controller and action are correct.
I have had success using a subclassed RazorViewEngine that only looks for C# views. I extended it to look in a specific controller folder for partials.
Using the CustomRazorViewEngine below and requesting /Home/Index which is calling Html.Partial("_SomePartial") inside it's view will look for partials in this order:
/Views/Home/Partials/_SomePartial.cshtml
/Views/Home/_SomePartial.cshtml
/Views/Shared/_SomePartial.cshtml
This is indeed returning the the partial views in the correct order.
public class CustomRazorViewEngine : RazorViewEngine
{
public CustomRazorViewEngine()
{
ViewLocationFormats = new[]
{
"~/Views/{1}/{0}.cshtml",
"~/Views/Shared/{0}.cshtml"
};
MasterLocationFormats = ViewLocationFormats;
PartialViewLocationFormats = new[]
{
"~/Views/{1}/Partials/{0}.cshtml",
"~/Views/{1}/{0}.cshtml",
"~/Views/Shared/{0}.cshtml"
};
}
}
Make sure that you are only using your subclassed view engine by clearing all existing and adding your new custom view engine.
Global.asax.cs
ViewEngines.Engines.Clear();
ViewEngines.Engines.Add(new CustomRazorViewEngine());
Related
Here is my route
Route::get('desktops/{desktop}','DesktopsController#getdesktop');
Here is my controller method
public function getdesktop($identifier)
{
$desktop = Desktop::all()->where('identifier',$identifier);
$casings = $desktop->casings();
dd($casings);
}
I have added the App\Desktop, here is my casings method defined inside Desktop Class/Model
public function casings()
{
return $this->hasMany('App\Casing');
}
Now it seems to be working on tinker, but when I open it in my browser it throws an exception of method not found or to be exact BadMethodCallException, even though I have method defined inside the class. I can't seem to figure out the problem.
When you define the relationship in your model it is carried in to the eloquent object as a property rather than a function inside the collection.
As such you need to access it without the ():
$casings = $desktop->casings;
You can find out more about accessing the relationships in the docs.
I was using this
desktop = Desktop::all()->where('identifier',$identifier);
which was returning a record set, with multiple records. Even though there was only 1 record, it was treating it as a collection. So I tried changing
desktop = Desktop::all()->where('identifier',$identifier)->first();
which only fetched me a single record and it worked.
I have two pairs of controller and view. The first view contains a list of items, while the in second shows some details of a specific item. What I want to achieve is that a click on one list item, the function onSelect should call second controller of detail view and update its content with the selected list item.
So far I have following code:
//first list controller
onSelect : function () {
var secondController = sap.ui.controller("controller.Detail");
secondController.updateFunction("some text");
}
Then in second controller:
//second detail-controller
updateFunction: function (someText) {
var view = sap.ui.xmlview("view.Detail");
view.byId("someTextField").setText(someText);
}
The problem is that this is not working. It seems that sap.ui.xmlview is not returning the same view which is displayed.
When I execute following code:
var model = view.getModel(model);
console.log(model);
within 2 functions of detail controller, but first is called by outside controller and second is called by onInit or function called by detail view event, the id is different.
How can I achieve such a cross-controller function calling with updating content of different view? Or is my approach not proper?
I would recommend to use either the EventBus or Routing for inter view communication.
Routing is nice as it uses the hash part (#) of the url to communicate for example an event like the selection of an item (f.e. https://example.com/myUi5App/index.html#/item/123). The user can use the browser history and bookmarks to navigate through your app.
A view can register to the router to be notified when a specific url pattern is matched. The walkthrough in the SAPUI5 Developer Guide does nicely explain routing step by step and in detail here and here.
EventBus is a global object that can publish arbitrary events. Anyone interested can register to the EventBus. There is an EventBus on the Component which you should use if you have a component and a global EventBus.
Both techniques help decoupling your views. It does not matter if there are one, many or none views listening to the selection change. And it does not matter for the listeners who fired the event.
If both views have been called once you can achieve this via the view (from my opionion, this is quite hacky and should be solved otherway)
this.getView().byId("yourViewId").oController.yourMethod();
means in your case
onSelect : function () {
var secondController = this.getView().byId("view_id").oController;
secondController.updateFunction("some text");
}
maybe this helps you, he is passing the controller reference which would be a better option: Calling Controller Function from inside a press handler in sapui5
I have found solution.
sap.ui.getCore().byId("__xmlview1");
According to documentation var view = sap.ui.xmlview("view.Detail"); always creates a new view.
However I am still struggling about specifying id of xmlview. Since "___xmlview1" is dynamicly given name and the number 1 means serial number of views within application. So if I create another view before creation of "view.Detail", the id will point to the new one.
I am creating xmlview like this:
<mvc:XMLView viewName="view.Detail"></mvc:XMLView>
I have a method that removes a Photo model from a Blog model. (Blog hasMany Photo). I do this through AJAX. And my method looks like this:
public function removeImage(RemoveImageRequest $request)
{
$parent = $this->model->findOrFail($request->parent);
// Check if a passed image belongs to the passed post
if(in_array($request->image, $parent->photos->lists('id')->all())) {
$this->repository->detachPhoto($parent, $request->image);
}
return $this->transformer->transform($parent);
}
Transformer is just a class that reformats the data for JSON, in a more readable way, plus adding some additional properties that are used on the front end.
But when I return that $parent object, it still has the recently deleted photo. Should I fetch the whole model again or is there a way to return a fresh copy?
You can reload parent's photos relation by calling:
$parent->load('photos');
Afterwards, the relation will hold what is currently in the database - the list of photos without the one you just removed.
I have built a MVCPortlet that runs on Liferay 6.2.
It uses a PortletPReferences page that works fine to set/get String preferences parameters via the top right configuration menu.
Now I would need to store there a String[] instead of a regular String.
It seems to be possible as you can store and get some String[] via
portletPreferences.getValues("paramName", StringArrayData);
I want the data to be stored from a form multiline select.
I suppose that I need to call my derived controller (derived from DefaultConfigurationAction) and invoke there portletPreferences.setValues(String, String[]);
If so, in the middle, I will neeed the config jsp to pass the String[] array to the controller via a
request.setAttribute(String, String[]);
Do you think the app can work this way in theory?
If so, here are the problems I encountered when trying to make it work:
For any reason, in my config jsp,
request.setAttribute("paramName", myStringArray);
does not work ->
actionRequest.getAttribute("paramName")
retrieves null in my controller
This is quite a surprise as this usually works.
Maybe the config.jsp works a bit differently than standard jsps?
Then, how can I turn my multiline html select into a String[] attribute?
I had in mind to call a JS function when the form is submitted.
this JS function would generate the StringArray from the select ID (easy)
and then would call the actionURL (more complicated).
Is it possible?
thx in advance.
In your render phase (e.g. in config.jsp) you can't change the state of your portlet - e.g. I wouldn't expect any attributes to persist that are set there. They might survive to the end of the render phase, but not persist to the next action call. From a rendered UI to action they need to be part of a form, not request attributes.
You can store portletpreferences as String[], no problem, see the API for getting and setting them
I think maybe you can use an array in client side, and you can update the javascript array, when user is selecting new values.
So you have the javascript array, then when user click on the action, you can execute the action from javascript also, something like this:
Here "products" is the array with your products.
A.io.request(url, {type: 'POST',
data: {
key: products
},
on: {
success: function(event, id, obj) {
}
}
});
From Action methd you can try to get the parameter with:
ParamUtil.getParameterValues(request,"key");
I have been working with ASP.NET but I am fairly new to the ASP.Net MVC 4 with Razor concept. So my question might be basic but I appreciate every help as I couldn't really find a definite answer for days now (Or I am looking for the wrong things). The question is: How do I access a Controller method within my view without using my Index Method?
The scenario:
I have a database that store some values like date, price etc ... (Variables are defined in the Model.
I have a controller thats sets a view index
I have a view that shows Indexpage with the values of my data base.
I want to sum all values of the price colum but dont want to store the result in my db.
In my understanding I access the db via a Method in my Controller class and call this method in my view.
To learn step by step I just defined a fixed value in my controller to see how to show this value in my view.
The code:
Model:
[Range(1, 100)]
[DataType(DataType.Currency)]
public decimal Price { get; set; } // Amount of an entry
Controller:
public ActionResult Index()
{
return View(db.Amounts.ToList());
}
public ActionResult ShowSumOfAllPrices()
{
//For testing db is not called yet. Query must be defined and result written to a variable within this mehod
ViewBag.Price = 2;
return View();
}
View:
#*testmethod for displaying sumprize (first just wit test result) via controler*#
<table>
<tr>
<td>hallo #ViewBag.Price</td>
</tr>
</table>
The result is not shown as long as I don't define the method content of ShowSumOfAllPrices() (in my controller class) in the index() method.
The question is: Is a result of a method in a view only visible if I define it within my Index() method in my controller or can I write an extra method like I did and call it in my view? It is working if I c&p the logic of ShowSumOfAllPrices() to Index(). But I don't think I need to define everything in my index method. If so, it would be a large and fat method. So as far as I see there are 3 possible ways but not all might be "nice" or even working:
Define everything in the Index() method.
Define other methods but call them in the Index method because it is the only way to display it within my view and not using the model because i dont want to store those data in my db
I can define other methods and directly call them in my view without having a new page but only the result of this method shown under the content of the currend Index Page.
I hope my question is understandable and this question was not asked like mine before.
Define everything in the Index() method.
Controllers are not meant to hold the logic.
Define other methods but call them in the Index method because it is the only way to display it within my view and not using the model because i dont want to store those data in my db
Don't define other methods in the controller itself. Make other classes and then call those methods in the Index() or any suitable controller method. And if you want to display data in the view , then model is the best choice, but you can even store your data in the ViewBag
I can define other methods and directly call them in my view without having a new page but only the result of this method shown under the content of the current Index Page.
If you want to fetch the result of the methods in the same view then this can be the case[might be using same kind of AJAX] but if you want to render other page , then this might be a bad idea.
The best thing you can do is to declare a class for your required function as Single responsibility principle and then use the class to do that operation in the method you want to have results in.You can access the controller methods using AJAX and JQuery, just google it out a bit and you will be your own.
Hope this helps.