Rendering collection view in CompositeView triggered constructor? - marionette

I have a composite view which has a task, and it's comments. I put it onto a contentRegion to display. When rendering model alone, it works fine. However when come to collection, it behaves really strange. console.log shows initialize function has been triggered twice. The first time is when define the view
taskView = new MyProject.Views.Task
model : task
collection : comments
I then do a MyProject.contentRegion.show(taskView) in order to render the model view. After that, I just call comments.fetch() to get all the comments. Then comes the problem, it re-initialized my taskView and the template keep complaining xxx is undefined.
Any thoughts? I know it's weird because another CompositeView in my project works great.

NathanInMac, I've done a little testing from your suggestion of using an itemView and found some interesting stuff.
Was your problem involving nested compositeviews'? As mine was but I'm unsure if that affects anything.
What solved the problem was initially trying a collectionView which couldn't find the itemView so I moved the definition of the itemView for the collectionView/compositeView to before the definition of the collectionView(or extended).
This seems to be a working fix and just a misleading bug with compositeView's double initializing instead of displaying some exception or error.

Related

CarouselView.FormsPlugin get index of specific page

I'm using Carousel View by alexrainman for creating custom wizard.
I need to get index of specific page by its type (I don't know exactly which index would that page have).
Something like this:
var indexAdvanced = MyCarouselView.GetIndex<ContentView>(typeof(AdditionalDefectParametersContentView));
but of course, this code doesn't work. While creating this question, I've got an idea with using CarouselView's ItemsSource. How to do it properly? TIA.
By the way, I've already found an answer. >_<
The resulting code is:
// My CarouselView consists of ContentViews
_indexAdvanced = MyCarouselView.ItemsSource.Cast<ContentView>().
IndexOf(view => view is AdditionalDefectParametersContentView);
So it works!
Don't know what should I do: delete this question or leave? Maybe It would be useful for somebody, so I'll leave it for now.

Wicket replacing panel with ajax fails with MarkupNotFoundException

the page markup has
<div wicket:id="stepPanel" />
tag in it and when the page is first loaded it works great that is
add(new MyFirstPanel("stepPanel"));
works fine. But then when I trigger an Ajax event and request redrawing
addOrReplace(new MySecondPanel("stepPanel"));
target.add(MyPage.this);
i get the following error
Last cause: Failed to find markup file associated. MyFirstPanel: [MyFirstPanel [Component id = stepPanel]]
please note that it tries to find the wrong markup (should look for markup for MySecondPanel) and it fails regardless it succedded to do so before!
I instantiate panels using reflection, but could it be a problem here? No exceptions thrown.
Anwser:
Actually it was something else - I have noticed that one of my AjaxSubmitLinks had reference to a form that was no longer placed in a markup... so whatever you do just remember not to leave that reference.
You are adding MyPage after replacing the Panel causing MyPage to re-render.
There is a good example on how to replace panels here.
Yes you can call panels via reflection. I don't clearly know what you are trying to do with event here but if you want you can attach your panel with AjaxSelfUpdatingTimerBehavior and define the duration which will update this component in the given time period.
Hope its useful.

knockout view model wrapped in observable

To avoid calling applyBindings multiple times on the same DOM element, I wrap my various viewmodels in an observable. then just change that observable to whatever view model i wanna see and BAM...that works.
until i do something like this:
<div data-bind="if:$data">
...some bindings in here
</div>
when i change view models, the bindings inside any "if:$data" blocks do not update.
here's a fiddle to really demonstrate this: http://jsfiddle.net/btrauma8/2TxME/
This would have worked properly prior to KO 2.2. In 2.2, we made if and ifnot more efficient by only re-rendering the section when the value actually changes between truthy/falsy.
There were many cases where people would bind against something like if: items().length and the entire section would be re-rendered everytime that an item was added.
In your case, you can overcome this pretty easily by just using the with binding instead of if. Since, you are binding against $data, it will not actually change the context and will give you the result that you are after.

Problem with passing non-literal text to the Html.Partial() extension method

I would like to pass the file name of a partial view as data retrieved from the viewbag as such:
<div id="Zone1">#Html.Partial(ViewBag.ZoneControl1)</div>
Where the "ZoneControl1" property of the ViewBag is the name of the desired partial view retrieved from elsewhere (i.e. database, web service, etc.). If I include the text as a literal string i.e.:
<div id="Zone1">#Html.Partial("Controls/MyPartial")</div>
It works just fine. If I pass that literal string as a property of the ViewBag from the controller, or even just create a variable in the consuming view, i.e.:
#{string zone1 = "Controls/MyPartial";}
<div id="Zone1">#Html.Partial(zone1)</div>
It doesn't work. The page appears to be loading but never displays anything in the browser. Again, this works fine if I hardcode the partial view name, but not if it is passed as data from a variable or property. Anyone know why this is happening? If this is intended or unavoidable behavior, is there a workaround?
You can't use dynamic in Html.Partial (which is what ViewBag is) because it accepts only strings. One quick way around this would be to cast your ViewBag.ZoneControl:
#Html.Partial((string)ViewBag.ZoneControl1)
As for the second part (zone1 = "Controls/MyPartial") I was unable to duplicate that.
The following code is what I wrote to test it and it works just fine.
#{ string zone1 = "Controls/MyPartial"; }
<div>#Html.Partial(zone1)</div>
I assume the answer with casting the ViewBag is what you're really looking for in this case.
Well, I have it working now and I'm not exactly sure what fixed it. I copied the razor code\markup and deleted that view and created a new view and pasted in the old code. The only difference was that when I created the new view, via the wizard, I specified to NOT use a master page and the resulting page had code to specify:
#{
Layout = null;
}
The original page was created using a master page and then I changed my mind and took out the layout directive entirely. Anyway, after making those changes, it WORKED! So, I initially surmised that the reason was that a view must specify "layout = null" if not using a master page. BUT, I then took out the "layout = null" code in this new page and it still worked! So... not sure what went wrong, but to sum up:
As #BuildStarted correctly noted, you can use a property of the ViewBag object as the partial view path, but you must cast it as a string for it to work properly. So, the premise for this question was incorrect and something else was mucking things up. Just not sure what.

Where should I implement this? View or ViewController?

I have to implement an Form View, or in other words: A class that is used to put a complex input form on the screen.
The Form is built up of FormComponents. There is an addFormComponent() Method to compose the form with these. And then, the form has an isValid() Method which will go through all the FormComponents and check their associated FormValidators.
For sure this thing has a lot of "intelligence", but most of this is just a call to some other class. For example the isValid() method does cool stuff, but it really only calls the isValid() methods of the FormComponents which are registered in an array. Nothing too fancy.
Well, that beeing said, must I make a fat FormViewController for this, or is an View just fine?
My understanding of these is, that a ViewController is used when there's some big logic involved. In this case, the Form View has a template which will simply iterate over the FormComponents and include them. Each FormComponent has it's own template in turn and does it's own stuff.
I've always been struggling with ViewController and View and I think I'll keep on doing that until I get a nice R.I.P. brick... but maybe someone can clear this up a little bit ;-)
The purist in me is saying that this belongs in a ViewController. I guess maybe it would depend on the framework you are using. For example, this type of setup would be very easily implemented in a Spring Controller object. It sounds like creating a controller in your case would be a lot of extra work.
Nothing is ever set in stone. You can implement in the View for now and if this turns out to be a huge burdon, move it to a Controller class. Knowing when to refactor is the difficult part.

Resources