Why HTML template references ViewController when it needs to fill data like {{hideCompleted}}?


#1

Hi, I am just going through To-Do tutorial an I am trying to understand the mindset behind Meteor since tutorial only says how to do things but it doesn’t explains why are things done that way.

Why HTML template references ViewController when it needs to fill data like {{hideCompleted}}?
But ViewController references HTML template to assign events to elements like
"change .hide-completed input": function (event) { … }?
I was under impression that in MVC View should have no knowledge on ViewController and its inner structure?
As it stands HTML template needs to know which function to call from ViewController to populate itself.
Shouldn’t populating parts of HTML Template be done similar to how event works?
That is ViewController should located specific element by using class and the structure of the HTML Template and then insert values in referenced element.
In other words if I change the name of the function {{hideCompleted}} inside controller to something else then I have to go through all HTML Templates that use that function and rename it there also.
Can I define event and handler function inside HTML Template?
Can I populate HTML Template from ViewControler to avoid referencing ViewControler functions/helpers from HTML Template?


#2

I’m note sure the templating is MVC but…

Having the controller knowing about the view also doesn’t lead to separation of concerns. Importantly, if the view calls {{hideCompleted}} to populate itself it does not know how Template.helpers.hideCompleted implements itself.


#3

"Having the controller knowing about the view also doesn’t lead to separation of concerns."
This is how ViewControllers should work. They need to know internal structure of the View they are connected to in order to be able to inject behavior into View using “change .hide-completed input”: function (event) { … }"
Separation of concern in case of ViewController is based that ALL the behavior of the View is moved to ViewController.
In such case View should not have stuff like onclikc=doSomething().
Instead View should only concern itself about defining STATIC structure, that is where each button goes but not on which event reacts and what should these events do.

But maybe I am confused because we are here talking about View Template and not the View. So maybe it is OK for ViewTemplate to reference controller function to populate itself with data but it is not OK to define events and events handler. They should be injected by ViewController. But the question remains.

Why is it OK for ViewTemplate to call ViewController functions to populate itself but it is not OK for ViewTemplate to define events and reference event handlers implemented inside ViewController.

For instance placing below code into HTML Template means that this template can be only be used to show some list.
Removing this stuff would allow us to use the template by putting something else inside.
Ans what is going to be placed should be defined by ViewController referencing class=“my1”

<div class="my1">

<ul>
  {{#each tasks}}
    {{> task}}
  {{/each}}
</ul>

#4

It may be worth reading @awatson1978’s cookbook around MVC and Meteor/Blaze.

TL;DR:

Model          HTML         What Is Displayed       
View           CSS          How It Is Displayed        
Controller     Javascript   When It Is Displayed*

*Not as snappy, but I prefer to think of this as Display Management

Also, if you’re interested in MVVM, check out @manuel’s viewmodel


#5

I have red cookbook1 and to me this is complete nonsense.
It is not true that HTML defines What Is Displayed.
It also defines How it is displayed.
For instance if HTML displays single record then attributes can be arranged on the screen in many different ways from which it follows that HTML defines HOW data is displayed and not just which data is displayed.

I watched the video from viewmodel1 and first it shows a solution which they say is bad since controller has knowledge of the view referencing view component through classes. What is confusing is that this is how Meteor tutorials teaches us to work. Then they show a better MVVM solution which has less code and in which View is referencing controller and controller has no reference to View. in other words it is the other way around.

This means that Meteor tutorials are showing us two completely different ways of working. Who references who is completely different in those two examples. It would be better if one example is really found to be better then the other then not to use inferior solution in main Meteor tutorial.


#6

@ivoronline, I think you have a very legitimate question here. I think it is important to not bring previous dogma like “I was under impression that in MVC View should have no knowledge on ViewController and its inner structure?”

First point: Meteor is not MVC.

You can do MVC-like patterns in Meteor, probably, but we are trying to come up with the best way to write apps, not the most MVC-compliant way.

Second point: Decoupling the view controller from the view is impossible

No matter what you do, either the view will have to reference the controller, or the other way around. Populating the data in the template from the controller by using JQuery-like CSS selectors will not solve any problems, because now the controller is still coupled with the view.

The real question for me, is: If I change my controller code, do I have to change my view/HTML code, and vice versa?

In my mind, the best system is one in which you have to do that only very rarely. I think referencing the helpers from the controller in the view by name is the best thing to do, because then you can easily change your HTML without having to change anything in the helper definition. Likewise, you can change anything in your helper without having to update the view, as long as you maintain the signature of the helper.

In reality, I think the React people got this right - it’s an issue of “separation of concerns, not technologies” - Just because part of the app is written in HTML and part is in JS, doesn’t mean that they are actually separate things. Having to write CSS selectors everywhere in your controller doesn’t decouple the code, it actually only couples it more.

@ivoronline I’m not sure what your point is about the template only being able to show a list. What’s the point of having templates at all if their only purpose is to be a vessel for the controller to inject HTML code?


#7

Follow up:

I think there is a small problem that event handlers are forced to reference the HTML structure with CSS selectors. IMO the solution to this is to enable people to reference event handlers by name, to maintain the same property that helpers have where you can safely move around HTML without breaking controller stuff.


#8

Thank you very much for your detailed answer. I appreciate when people are interested in theoretical discussions about why things are the way they are and not just following rules as if they are set in stone. When I made the post I just felt that something might be off in the way things function and I tried to describe why I felt this way the best I could. Your reasoning helped me understand better why I had that feeling. So I would like to add additional clarification.

In the HTML template we use {#each posts} to reference helper posts.
This now means that this template can only be used to show list of posts.
To show list of users I would need to create new template that looks exactly the same except for word posts being replaced with word users. When two things look exactly the same except in some detail maybe they should be parameterized like a function.

Wouldn’t it be better if instead we had {#each #param1#} which controller could reference and populate with its helper method?
This way single HTML template could be reused by multiple controllers to show the lists of different collections. This would be reusable list component capable of listing items of any collection. #param2# would be template showing how to present properties. #param3# would be list title. Something like that.

Additionally:

  • all referencing is done in the same direction, from controller, which gives consistency
  • HTML template now only defines static structure. It is just a shell. It doesn’t know which data is supposed to show or which function should give its data. It is just standing there looking pretty and completely empty.
  • all the dynamics and logic is inside controller. Controller defines from where to get data. It also injects events.

I am just trying to make sense of things since I have hard time using something if I don’t understand why is it working the way it is. I have just started learning meteor (going through book) so maybe there is some functionality that I am not aware off that does similar.

Is there a way in meteor to programmatically create view components like lists, tables, buttons in order to avoid having to work with HTML and CSS? Is Meteor Ionic about that? I took a short look at Meteoric tutorial and it didn’t seem to follow Meteor simplicity.