title: Knockout components click event from parent
body: <p>Lets assume that i have a modal, where there is a FileUpload component in the modal-body made from jquery-file-upload.</p>
  
  <p>This component has a method called "Upload" in the viewmodel, which goes through selected files and uploads them. </p>
  
  <p>Now, I want to upload the files when i press the "upload"-button on the modal. Which is the best and cleanest way to make this happen ?</p>
  
  <p>My code right now is like this (be aware that it's just some quick prototype code):</p>
  
  <pre><code>&lt;div data-bind="component:{name:'FileUpload', params:FileUpload}"&gt;&lt;/div&gt;
  
  &lt;button data-bind="click:test"&gt;test&lt;/button&gt;
  @section Scripts
  @Scripts.Render("~/scripts/global/fileUpload")
  @Styles.Render("~/Content/css/fileUploadCSS")
  &lt;script type="text/javascript"&gt;
      var model = function () {
          var self = this;
          self.FileUpload = {
                  url: 'test',
                  onFailed: function (e, data) {
                      console.log('failed')
                  }
          };
          self.test = function () { console.debug(self.FileUpload) }
  
      }
  
      ko.applyBindings(new model(), document.getElementById("main"))
  &lt;/script&gt;
  End Section
  </code></pre>
  
  <p>And the component itself:</p>
  
  <pre><code>ko.components.register('FileUpload', {
  viewModel: function(params) {
      var self = this;
      self.files = ko.observableArray();
      self.template = params.template;
      self.multiple = params.multiple || false;
      self.progress = ko.observable(0);
      var acceptFileTypes = params.acceptFileTypes || /(\.|\/)(gif|jpe?g|png|pdf|eps|tiff|cdr|PDF|CDR|JPG|EPS|TIFF|pptx|docx|xlsx|ppt|doc|xls)$/i;
      var maxFileSize = params.maxFileSize || 104857600;
      self.Upload = function() {
          $.each(self.files(), function(index, file) {
              file.submit();
          });
      };
  
      self.options = {
          type: params.type || "POST",
          dataType: params.dataType || "json",
          formData: params.formData || {},
          url: RTC.SiteUrl() + params.url,
          sequentialUploads: params.sequentialUploads || true,
          dropzone: params.dropzone||$(this),
          autoUpload: params.autoUpload || false,
          forceIframeTransport: true,
          limitMultiFileUploadSize: params.maxFileSize || maxFileSize,
          maxFileSize: params.maxFileSize || maxFileSize,
          done: function (e, data) {
              if (params.onUploaded)
                  params.onUploaded(e, data);
              RTC.Progressor.Done();
          },
          fail: function (e, data) {
              if (params.onFailed)
                  params.onFailed(e, data);
              RTC.Progressor.Done();
          },
          start: function(e,data) {
              RTC.Progressor.Start();
          },
          progressall: function(e, data) {
              RTC.Progressor.Set(data.loaded / data.total*100);
          },
          add: function (e, data) {
              //if (data.originalFiles[0]['size'] &gt; maxFileSize) {
              //    RTC.addAlert(RTC.translate(220, "[220: File is invalid]"), "alert-danger", RTC.translate(193, "[193: An error occurred]"));
              //} else if (!acceptFileTypes.test(data.originalFiles[0]['name'])) {
              //    RTC.addAlert(RTC.translate(198, "[198: Wrong file format]"), "alert-danger", RTC.translate(193, "[193: An error occurred]"));
              //} else {
                  self.progress(0);
                  if (!self.multiple)
                      self.files.removeAll();
                  self.files.push(data);
             // }
          }
      };
  },
  template: { element: "fileUploadTemplate" }
  });
  
  ko.bindingHandlers.fileUpload = {
  update: function (element, valueAccessor) {
      var options = valueAccessor() || {};
      //initialize
      //.fileInput || $(this),
      $(element).fileupload(options);
      ko.utils.domNodeDisposal.addDisposeCallback(element, function () {
          // This will be called when the element is removed by Knockout or
          // if some other part of your code calls ko.removeNode(element)
          $(element)("destroy");
      });
  
  }
  };
  </code></pre>