Cannot find element using UI in layout layout

I'm not sure why I can't get the button element using my UI hash. This is what my layout looks like:

Layout: App.Base.Objects.BaseLayout.extend({

   // Rest of the code left out for brevity
   ui: {
      btnSave: "#btnSave"
   },

   events: {
      "click @ui.btnSave": "onSave"
   },

   onInitialize: function () {
        this.listenTo(App.vent, "DisableSaveButton", function(val) {
            this.disableSaveButton(val);
        },this);
   },

   disableSaveButton: function () {
        this.ui.btnSave.prop("disabled",val).toggleClass("ui-state-disabled",val);
   },

   onSave: function () {
        alert("saved!");
   } 
})

      

In VS2013, when my breakpoint hits a line inside the disableSaveButton method, I entered $ ("# btnSave") into the Watch window and I was able to get the item back. I could tell because it had a length of 1. From this I know that the button is displayed. However, if I enter this.ui.btnSave into the Watch window, I would get an item with a length of 0.

My BaseLayout object is basically a custom object extended from Marionette.Layout

Puppet version: 1.8.8

Any ideas why I can't find the button element using this.ui.btnSave?

Thanks in advance!

+3


source to share


1 answer


Got some help from a colleague and the problem might be the item is out of scope. Basically, inside a Layout object, 'this' does not contain an element. We were able to replace 'this.ui.btnSave' with '$ ("# btnSave", this.buttonset.el)' and it works great. buttonset is the area that actually contains the html element.

This looks like an inconsistency because although the ui hash doesn't work, the click event using the ui hash does work.

UPDATE 6/3/2015: Another colleague of mine provided a better solution. Basically, in my layout, I am using the display function to display my view. It looks something like this:

 Layout: App.Base.Objects.BaseLayout.extend({
      // Rest of the code left out for brevity
      display: function() {
           $(this.buttonset.el).html(_.template($("#buttonset-view").html(), {"viewType": viewType}));
      }
 })

      

Basically what I'm saying is to set the html of my region, which is this.buttonset.el, to my html template. At the moment, my layout doesn't know any elements inside the region. It just contains an area that displays the items. So there is some kind of junction between my location and the elements in my region.

The correct solution, unlike my previous workaround, is to simply add the following line of code at the end:



this.bindUIElements();

      

From Marionette Annotated Source:

This method binds the elements specified in the "ui" hash inside the renders code with the appropriate jQuery selectors.

So this final code looks like this:

Layout: App.Base.Objects.BaseLayout.extend({
          // Rest of the code left out for brevity
          display: function() {
               $(this.buttonset.el).html(_.template($("#buttonset-view").html(), {"viewType": viewType}));
               this.bindUIElements();
         }
})

      

With this, I was able to finally get my element using this.ui.btnSave.

+2


source







All Articles