Search code examples
javascriptbackbone.jstriggersmarionette

Trigger a child view model method in the parent view : MarionetteJs


I have a Marionette view SingleCategoryView that takes a collection and renders a Collection view optionsView. the optionsView is a list of an itemView optionView. In my SingleCategory view I have to do a test onRender

 "onRender": function() 
 {
   if(optionsView.hasOnlyExtraOption(optionsView.collection.models)) {
   var noResultsAvailableMsg = 
   this.model.getLocalisationModel().getNoResultsAvailableMsg(); 

   var myModel = new noResultsAvailableModel({noResultsAvailableMsg: 
   "noResultsAvailableMsg"});
   this.conflictMessageRegion.show(new noResultsAvailableView({ 'model' : 
   myModel}))} 
 }

here is the code of the hasOnlyExtraOptions located in the optionsView file

"hasOnlyExtraOption": function(data) {
    return data.every(function(currentValue) {
        return 
         currentValue.get(
         MODEL_VIEW_CONSTANTS.ctaDisplayConflicted.selectors.cfgExtraOptions
          ListItem) || 
           currentValue.get(
        MODEL_VIEW_CONSTANTS.ctaDisplayConflicted.properties.isExtraOption);
                });

            }    

My problem is when I am doing the test even if the singleCategory is render the css class ( isExtraOption cfgExtraOptionslistItem ) are not setted yet so the result of the test is undefined. Actually these css class are setted by the optionViewModel here :

"onConfigurationStepsComplete": function() {
 // some code 
  this.setIsExtraOption();
  //some code }

to be more explicit : optionView has as parent optionsView, witch has singleCategoryView as parent. My aim is to trigger the change of the attribute isExtraoption by the optionViewModel from the singleCategoryView.

Thank you in advance .


Solution

  • You can use child event bubbling for the collection view and item view. i.e trigger a method from the child view once the configuration is fetched, and execute code in parent view in turn. for eg, in child view:

    // optionView
    doSomething() {
       this.triggerMethod('did:something', this);
    }
    

    And you can listen to this in the parent view like:

     // optionsView
     onChildviewDidSomething(childView) {
        console.log('Something was done to ' + childView);
     }
    

    Above will propagate the event until optionsView in your case. You can then use normal trigger and listen mechanism to propagate it further up.

    For eg, trigger another event from optionsView like:

    // optionsView
    onChildviewDidSomething(childView) {
        console.log('Something was done to ' + childView);
        this.triggerMethod('collectionview:did:something', this);
     }
    

    And you can listen to this event from the parent view, which in your case is singleCategoryView, something like:

    // singleCategoryView
    this.optionsView.on('collectionview:did:something', this.handler);