I am creating a web based software using Asp.net MVC 5 with EF framework on Visual Studio 2013.
I have a view page which needs to display two partial views at a given time. The partial views are associated with 2 model classes thus will be be from two Controllers. How to specify which frame the partial view should be displayed?
I'm new to MVC 5 so I am unable to provide a more detailed description. Any suggestion that can get me the result below would be helpful
At least a couple of options:
1 #Html.Action
Just use #Html.Action (twice) to render the partial views using separate controller calls:
e.g.
#Html.Action("action1", "Controller", new { id = Model.idOfPart1 }
#Html.Action("action2", "Controller", new { id = Model.idOfPart2 }
Where the id's are the key/lookup values you would normally pass to a control if they were full views.
Action() causes a full call to the action of the controller specified and renders the result in-place in the parent view.
2 #Html.Render
If instead you wish to pass a combined ViewModel to the parent view, and send parts of the model to each partial view, you can use #Html.Partial:
#Html.Render("ParialView1", Model.model1);
#Html.Render("PartialView2", Model.model2 }
This version passes specific models requesting each partial view render with it.
Render() is probably the most common model for passing data to partial views, but it really depends on how you want to pass the data around and how your controllers are structured. I always use Action when I think a partial view should be able to function as a view as well as a partial view.
Related
How does one pass a parameters to a Presenter? Reading the documentation there doesn't seem to be a way.
https://fuelphp.com/docs/general/presenters.html
Controller
$points = Presenter::forge('points', 'viewmy');
$points->set('id', 5);
Presenter class or view (I tried both):
var_dump($id);
var_dump($this->id);
Both var_dumps generate an undeclared variable error
This in the Presenter class also did not work:
$id = $this->get('id');
From the page you linked:
In your code, Views and Presenters are interchangeable. You can return Presenters from your controller actions, you can set a Presenter as a Theme partial, or assign it to a section of your page template. The basic API of the Presenter is compatible with the View. This makes it easy to swap a View for a Presenter in your code without having to do a major code overhaul.
They have the exact same interface as regular View objects.
So as per https://fuelphp.com/docs/general/views.html you can do things like using the set() method or passing the parameters in the forge() method.
I finally got to the bottom of this issue. I was using the setview function in my Presenter to change based on condition. This was meaning that any values that I had set were getting lost.
Passing the view into the 4th parameter of forge and not setting it in the presenter fixed this issue.
Basically my scenario is the following: I have 1 View bound to a ViewModel, with a List of items(the items' class is a class in my Model). Every time an item is selected from the list in this 'List View', its fields are edited in another, 'Details View'. This is identical to the Customer Management sample scenario, where a customer is selected from the List (in a 'List View') and the the Customer's details can be changed in a 'Details View'. The added quirk in my scenario, is that I want the changes done to the item in the Details View, to be reflected back in the List View. The changes are saved in DB from the Details View.
Also, depending on the changes done in the Details View, the item can be removed from list in the first View. Note that this is not deleting the record from the DB, because the list in the List View is just a filtered list of the items in the DB. I figured out two possible ways that I can do this:
By binding the 2 Views to the same View Model
EDIT: How do I call the second view? Will the second view actually use the same instance of the shared ViewModel?
-or-
2. By passing the item selected in the List View by reference to the Details View. Therefore in this case, I'm maintaining the 1-View-to-1-ViewModel mapping.
My questions are:
how can I implement scenario 1,
in 2, does the Init() method(used in conjunction with the ShowViewModel() method) support passing parameters by
reference?
I would be grateful, if you could include code snippets/examples in your answers.
Thanks a lot in advance,
binding 2 Views to the same View Model
You are free to set the ViewModel property on any View manually if you wish to. Simply set ViewModel = foo; before the call to base.OnCreate(), base.OnNavigatedTo() or base.ViewDidLoad()
in 2, does the Init() method(used in conjunction with the ShowViewModel() method) support passing parameters by reference?
MvvmCross does not support passing objects between ViewModels. On Windows Phone navigations are performed by url parameters. On Android, navigations are performed by Intents - these underlying mechanisms simply do not let you pass actual object references.
In general I handle this situation using messaging from the data store to the ViewModel
I would be grateful, if you could include code snippets/examples in your answers.
You can see how I typically do this in N=12 to N=15 in http://mvvmcross.wordpress.com/
I have recently been looking for a way to bind data in WinForms using MVVM.
I ended up creating a custom implementation of the MVVM pattern.
However, due to the lack of two-way binding, I have decided to give WPF a try.
I already have the Model, which encapsulates the non-ui functionality. For example the Model reads a configuration file, has a few properties, listens for incoming data on a socket, and saves incoming packets if needed.
Some of the Model's properties throws an exception if they are set out of range. I.e. the validation is done in the Model.
How is validation usually done in WPF? I have read a good deal of articles, and there seems to be some consistency in putting validation in the ViewModel. In fact, most articles only use ViewModel and View. Has the Model been buried?
Glad to see your decision to move away from custom implementations of MVVM when so much already exists that just ... works.
WPF is very strong for two way binding and that gives it its' greatest strengths.
The view model is bound to the view and acts as the mechanism to communicate with the data layer. Also Entity Framework (if you are on framework 4.0) will give you a great data layer for populating your entities in your ViewModel. This basically becomes your Model. It gives you an encapsulated form of UnitOfWork as well as Repository patterns.
While your view model in all examples are usually on a one-to-one basis, if the design calls for it you can have view models that span multiple views. I have a "menu" which displays key identifiers from each item in the list and a detail form that shows all fields for editing from the same object. So I span the view between the two.
You can hard code the view model in the xaml binding it to the datacontext or you can use Unity and inject the viewmodel into the view. Unfortunately the injection requires adding one public property for the purpose of setting the datacontext. So you'd have code like this:
public class MyView:Window
{
public MyView(MyViewModel model)
{
InitializeComponent();
ViewModel = model;
}
public MyViewModel ViewModel
{
set{ this.DataContext = value; }
}
}
So the rest is just TwoWay binding for each field and the setter can encapsulate single value editing. Your error message can even be bound to a text field on the form and it displays when the value is not null.
Also if you dig into Unity you will also get a truly great function called Event Aggregation which basically provides a vehicle for publish/subscribe of events and that ties into your ICommand implementation when getting a button click handled.
How can I eliminate to write $object = new Application_Model_Database() in every controller?
For example for an article controller, I have to type $articles = new Application_Model_Articles() for every controller. Should I put it under viewer controller, action helpers, or any other way?
Your question almost sounds like an OOP best practices question as opposed to a Zend Framework specific question. Regardless of whether or not I'm using a framework, and regardless of what framework I choose, I base when and where I create new objects on testability how many times I have to write $object = new My_Random_Object();.
Speaking specifically to the Zend Framework: Objects I'm going to use everywhere, or almost everywhere, get created in Bootstrap.php. These objects generally include a database adapter, logger, view object, and any plugins I might use. To access these across the application, I'll create private properties in the appropriate controllers and assign the objects to those properties in the controller's init() method.
class ExampleController extends Zend_Controller_Action
{
public function init()
{
$bootstrap = $this->getInvokeArg('bootstrap');
$this->_db = $bootstrap->getResource('db');
$this->_log = $bootstrap->getResource('log');
// and so on, and so forth
}
}
Ideally, models, services, daos, etc, will all be relatively tightly grouped by controller and by action. In my experience, and this is speaking generally, if I have the same model or service class showing up across all of the controllers in my application, I have an organization problem. That being said, any model that shows up in only one action gets created in that action. If it's across actions in a controller, it gets created in the init() method and assigned to a property. If it shows up across multiple controllers, it gets created in my Bootstrap.php.
(Ideally, everything gets created in the Bootstrap.php, so you can swap out that bootstrap for testing purposes. Sadly, I don't always do that, and I most often use the principles I outlined above.)
Well do you really need it in every controllers? Because that's pretty much by design. You implement models when you need them. Its not that much code really.
Now if its to be used across actions from a controller you could always:
class MyController extends Zend_Controllers{
$protected $_articleModel;
...
and in your constructor or __init() function initialize it so you can use it in every action thru $this->_articleModel
If you REALLY want it everywhere in your application just initialize it in your bootstrap and store it in the registry.
public function __initModels(){
$articles = new Application_Model_Articles()
Zend_Registry::set('articles', $articles );
}
And access it in your controllers like so:
Zend_Registry::get('articles')->fetchAll();
But then your still writing a couple of characters.
Hope this help!
IF you want to use models in the controllers you must call it..anyway some shortcuts are here
1.You can initialize it in the init section of your controller like
public function init(){
$this->object = new Application_Model_Database();
}
So that the this->object is available in all the actions of that particular controller
2.Use Zend_registry as suggested in the above answer
Another possibility is to use a Dependency Injection container, such as the Symfony DI component. It takes care of instantiating your objects, and you get some additional benefits:
Separation of concerns. You have a component devoted to create your object tree.
Easier testability of the objects.
Last, but not least, the performance benefits given by lazy instantiation (objects are created only when you ask for them). Thus, if some object is not used by the particular controller serving your request, it's not instantiated).
It's a bit more laborious than the above solutions, but much more flexible if you need to maintain and extend your application in the future.
Hope that helps,
If you are using this object to just display data in your view and are using your controller to grab the data and assign it to your view, like so:
//someControllerAction
$object = new Application_Model_Articles();
$object->fetchAll();
//assign to view
$this->view->articles = $object;
You might be better off making a view helper similar to:
//Articles.php put in /application/views/helpers
class Zend_View_Helper_Articles extends Zend_View_Helper_Abstract {
public function Articles() {
$articles = new Application_Model_Articles();
$articles->fetchAll();
//return rowset object
return $articles;
Then in your view (phtml) you could do something like:
//someView.phmtl
<?php $articles = $this->Articles(); ?>
<h1><?php echo $this->escape($articles->title); ?></h1>
<p><?php echo $this->escape($articles->body); ?></p>
building a view helper allows you to bypass the controller completely if you just need to display data from the model. This is a very simple example and can be used with partials and partialLoops.
REF:ZF reference Custom View Helper
ZF partial view helper reference
In the "Admin" area of my application, an object must be available in ViewData on every page (for display in the Master template). I have already inherited from Controller, so I cannot make a simple base class that handles it. What is a good solution of doing this when not using inheritance? An ActionFilter seems interesting but I don't want to put it on every controller in the Admin area. I'm considering the following:
Custom ControllerFactory that detects Area as well
Application_BeginRequest(), though I have no knowledge on executing controller then.
Maybe you have a better solution?
In this case I would create a separate action that executes a partial view that shows the data you need. In my opinion this is the most clean solution for this kind of problem and it's easily testable and reusable.
i have a dropdown on my masterpage. you dont need viewdata for it. i did it like this
code on masterpage:
<%= Html.DropDownList("schselectr", MVC2_NASTEST.MvcApplication.masterSchooljaarList())%>
in Global.asax.cs
public static SelectList masterSchooljaarList() {
NASDataContext _db = new NASDataContext();
List<Schooljaar> newlist = _db.Schooljaars.ToList();
return new SelectList(_db.Schooljaars.ToList(), "Sch_Schooljaar", "Sch_Schooljaar");
}
so simply, it calls the method, which returns the data i need, every time you load the page. easy, clean, effective.