fairly new to javascript and backbone Marionette, and I cant seem to figure out how to do this.
I want to select a child view from a compositeView by index (or any of the other selectors the docs say are available for the inherited collectionview (from babysitter).).
ie from within myCompositeView:
someMethod: function(index){
this.children.findByIndex(index);
},
...
how can I access the collectionView from a compositeView such that I can findByIndex or findByModel etc and get a reference to the actual Marionette View?
thanks.
Make sure you're using v1.0.0-beta6 of Marionette, as this is where the feature you need was introduced.
CompositeView extends directly from CollectionView, so calling this.children.findByIndex should work, as long as you're using the right version of Marionette.
Related
I'm still learning GWT, yet already have to face some kind of challenge for a work I have to do. Can't show any specific code so I'll try to explain it well.
Here's the situation: A certain class "Navigator" creates and save the Presenter instances of my architecture to allow reusing them. There is a method show() inside that same class that actually displays the view related but that system only works full screen by calling RootPanel.get().
What i'd like to do is showing that presenter instance's view inside of a flex panel element declared in a class myView (related to a class myPresenter) that basically uses Flex Panel to structure it's content.
To make it maybe more clear:
class myView{
...
flexPanel.setWidget(firstWIdget)
flexPanel.setWidget(secondWidget) //secondWidget to be replaced by a "thirdWidget"
...
}
I'd like the secondWidget to be replaced by another one, let's call it thirdWidget, that consists of a specific presenter instance's view.
To resume, I'd like my presenter instance's view to not go full screen but only occupy a certain area of the screen.
The displaying is managed almost entirely programmatically, means very limited use of css files and no use at all of xml ui files.
How can I manage this ?
Thanks
Use a SimplePanel as a container for your views returned by your Navigation class instead of adding them directly to root panel, and use that instance of SimplePanel where ever you want.
My EmberJS app is confusing me a lot at the moment. I have a collection view, that in turn defines an itemViewClass of a custom view I have defined in my code. Something like:
App.CarouselView = Ember.CollectionView.extend({
itemViewClass: App.SlideView.extend(),
});
And this CarouselView is rendered inside a template that has a dynamic segment backing it (I hope this makes sense?) . The controller for these dynamic segment is an array controller because the model for these dynamic segments is a collection :) (more confusion, please let me know)
App.SlidesController = Ember.ArrayController.extend();
By now all of you have figured that I am basically rendering a bunch of slides inside of a carousel. And these are dynamically backed in the collectionView by setting the property
contentBinding:'controller' // property set in CarouselView, controller corresponds to SlidesController
The confusion begins now. I want to add a slide to the existing set of slides. So I provide a button with an action : 'add' target='view'
In the SlidesView,
actions:{
add: function(){
var carouselView = this.get('childViews')[0];
// SlidesView has carouselView and another view as it's child, hence this.get('childViews')[0] is carouselView
var newCard = carouselView.createChildView(App.SlideView.extend());
carouselView.get('childViews').pushObject(newCard);
}
}
The above piece of code sucks and hurts me bad. I want to basically add a new SlideView to my CarouselView collection programmatically upon a button trigger. But apparently Ember recommends that childViews should not be manipulated directly and I ought to instead change the underlying content.
It states in my console.log that manipulating childViews is deprecated etc.
So essentially I need to add something to my content to my SlidesController content ? However, I don't want to add something to the content, this is just a soft add, that is providing the user with a slide so that he may choose to edit or add something if he wants to. He can always discard it. A hard add that will require me to persist the new slide to the DB will come once the user decides to save this information.
I have no idea what am I missing here but I'm not able to pass additional parameter to a CollectionView, like so:
View definition is very basic:
class UI.Elements extends App.Views.CollectionView
itemView: UI.Element
And then instantiated with these options:
getUIsView: (uiobjects, itemView) ->
options =
collection: uiobjects
variationView: itemView
new App.VariationsApp.UI.Elements options
With this code the view is being created fine, except the variationView is no where to be found. From backbone documentation:
When creating a new View, the options you pass — after being merged into any default options already present on the view — are attached to the view as this.options for future reference
But my CollectionView doesn't have options property on itself.
Really, I don't have any idea what am I doing wrong. Any help would be greatly appreciated because I'm stuck.
Any parameter you provide your view that aren't recognized as Backbone/Marionette options will be attached to this.options within the view. So you should have access to the variationView by accessing this.options.variationView.
If you need to access that information in the template, you need to pass it along by writing a serializeData function.
You can see an example of this in practice here: https://github.com/davidsulc/marionette-gentle-introduction/blob/master/assets/js/common/views.js
I use Ember.js (1.0. RC) and would like to apply Isotope.js's functionality to some of my views located in a "container".
So my route basically loads the models containing the needed data from a server, sets up the controller's content and binds it to the model's data, which works fine.
Next I declared a template for my IndexRoute which iterates over all the loaded items like this:
{{each item in this itemViewClass="App.ItemView"}}
The items are the images that should be filtered with isotope.js. ItemView only refers to a simple template for the time being.
The execution chain is the following: Route -> Fetching model data -> Set up controllers -> Create IndexView -> Pile up all the ItemViews in a DIV-container.
Now I need to check whether all the ItemViews are loaded and the rendering is finally finished to apply isotope.js's filtering functionality but I can't figure out how to do that.
The didInsertElement of the IndexView event fires as soon as it's been rendered and before the ItemViews were added to the DOM.
I already tried to set up a ContainerView which would work in conjunction with Ember.run.scheduleOnce("afterRender"...) if I didn't fetch the data through the models but hardcoded it to the content variable.
The CollectionView also did me no favor with this exercise.
Any ideas how to solve that misery? I'd really appreciate it. Thanks.
I am not sure how exactly isotope.js works..considering its just a jquery plugin, you can call isotope like this even if it is a ContainerView or CollectionView.
didInsertElement: function() {
Ember.run.next(this, function(){
this.$().isotope({}) // or watever code u want to write
});
}
This makes sure that the code inside ember.run runs once rendering is done completely..
Referring to this post on Backbone.EventBinder, I am lost on how to use EventBinder with Backbone views (which is the most popular use case). Is it still recommend to add a close() method to the Backbone.View prototype and a onClose() method to the view as suggested in this post? Also where does one store the binder object, so that binder.unbindAll() can be called on close? What is the recommended way to close child views (e.g. a parent view on a collection which has child views on the associated models). A working example would be a great addition to the Backbone.EventBinder project.
Yes, you should still add a close method to your views. The EventBinder does not negate any of what that Zombies post says. Rather, it helps to automate a lot of the process by making it easier to unbind all of your events within the view.
Take a look at the Marionette.View source code for an example of how it's used:
https://github.com/marionettejs/backbone.marionette/blob/master/src/marionette.view.js#L9
https://github.com/marionettejs/backbone.marionette/blob/master/src/marionette.view.js#L16
https://github.com/marionettejs/backbone.marionette/blob/master/src/marionette.view.js#L97
If you're using Marionette, you don't need to add the close method yourself, or add the event binder yourself. That's handled for you.
If you want to add this to your own views, it's easy:
MyView = Backbone.View.extend({
initialize: function(){
// add the event binder
this.eventBinder = new Backbone.EventBinder();
// bind some stuff
this.eventBinder.bindTo(this.model, "change:foo", this.doStuff, this);
},
close: function(){
// ... other stuff
this.eventBinder.unbindAll();
}
});