2014-10-28 59 views
0

我有一个方法在我的viewModel中调用ajax get方法来获取所有项目。这一切都很完美。然后我有一个ko.bindingHandler,用于通过ajaxSubmit内联上传图像。这也适用,但问题是我必须复制代码来获取bindingHandler中所有上传图像的项目,否则一旦上传图像就不会更新。刷新页面可以解决问题,但我希望视图能够自动刷新新图像。所以真正的问题是可以从bindingHandler中的viewModel调用一个函数吗?任何帮助将不胜感激!如何从ViewModel中调用一个函数bindingHandler

BindingHandler:

ko.bindingHandlers.imageInLineUpload = { 
    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     var options = ko.utils.unwrapObservable(valueAccessor()), 
      property = ko.utils.unwrapObservable(options.property); 

     $(element).change(function() { 
      if (element.files.length) { 
       if ((element.files[0].type === "image/png") || (element.files[0].type === "image/jpeg")) { 
        var $this = $(this); 
        $(element.form).ajaxSubmit({ 
         url: $.API.url + "XYZ", 
         type: "POST", 
         dataType: "text", 
         success: function (data) { 
          toastr.success('Upload Successful.'); 
          var viewModel= new MyViewModel(); 
          viewModel.GetObjects(); 
         }, 
         error: function (jqXHR, textStatus, errorThrown) { 
          toastr.error('Upload Failed. Please Try again!'); 
         } 
        }); 
       } 
       else { 
        toastr.error('Upload Failed. PNG and JPEG are the only supported formats.'); 
       } 
      } 
     }); 
    } 
}; 

视图模型:我在过去已经使用

var MyViewModel = function() {  
    var self = this;  
    self.xyz = ko.observable("");  
    self.xyz = ko.observable(""); 
    self.xyz = ko.observable(""); 

    self.GetObjects= function() {  
    // Ajax call to fetch objects. 

    } 
    self.GetObjects(); 
}; 

ko.applyBindings(new MyViewModel()); 

回答

1

有几种方法可以做到这一点。从字面上“调用从bindinghandler一个ViewModel功能”的方法是做:

var viewModel = ko.dataFor(element); 
viewModel.GetObjects() 

这是可行的,但它是一个非常平庸的解决方案;它非常紧密地将你的绑定处理程序耦合到这个特定的viewModel,它是一个隐式依赖; bindingHandler API并没有说清楚这个函数是否需要。


另一种方法(在我看来,一个更好的方法)是函数传递到bindingHandler作为一个选项参数:

<div data-bind="imageInLineUpload: {getImagesCallback: GetObjects}"></div> 

在bindinghandler:

var options = ko.utils.unwrapObservable(valueAccessor()), 
    getImagesCallback = options.getImagesCallback; 

getImagesCallback(); 

(这与PW Kad的答案类似,但我认为指定一个单独的bindingKey为不同的绑定处理程序提供选项对​​于所需的参数来说是一个糟糕的主意,并且是一种非常难看的方式来执行knockout绑定句柄RS,这一比例仅为传递对象到当前绑定左撇子)


不过说真的,如果你的绑定处理程序做asyncronous电话,我认为你需要重组的东西。在我看来,绑定处理程序应该只做视图逻辑,而不是处理ViewModel中应该存在的AJAX。

+0

得到它的工作!必须添加“$ root”。在函数调用前面。这工作完美!谢谢! – mikemike396 2014-10-29 13:13:04

1

的一种方法是向函数的引用传递到所述结合的处理程序作为一个选项类似于我们如何在其他地方使用回调 -

<div data-bind="imageInLineUpload: someObservable, imageILUOptions: { callback: myFunction }"></div> 

,并在您绑定的处理程序,您可以访问这样的功能 -

ko.bindingHandlers.imageInLineUpload = { 
    update: function (element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) { 
     var options = ko.utils.unwrapObservable(allBindingsAccessor).imageILUOptions; 
     var callback = options.callback; 

     // do something 
     callback(someVar); 

这可以让你的任何功能传递到结合,并将其作为它里面的回调。这不是一个完美的解决方案,但应该得到你所需要的。

+0

此方法有效,但我同意@Retsam。谢谢回复! – mikemike396 2014-10-29 13:18:26

相关问题