I have a method inside my viewModel that gets calls an ajax get method to fetch all of the items. This all works perfect. I then have a ko.bindingHandler that is used to inline upload images via ajaxSubmit. This also works, but the issue is I have to duplicate code that fetches all of the items inside the bindingHandler that uploads the images or else the image wont update once uploaded. Refreshing the page fixes the issue but I want to have the view auto refresh with the new image. So the real question is it possible to call a function from the viewModel inside a bindingHandler? Any help would be greatly appreciated!
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.');
}
}
});
}
};
ViewModel:
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 ());
There's a couple ways to do this. The way to literally "call a viewModel function from the bindinghandler" is to do:
var viewModel = ko.dataFor(element);
viewModel.GetObjects()
This will work, but it's a pretty mediocre solution; it pretty much tightly couples your binding handler to this one specific viewModel and it's an implicit dependency; the bindingHandler API doesn't make it clear that this function is needed.
Another way (in my opinion, a better way) is to pass the function into the bindingHandler as an options argument:
<div data-bind="imageInLineUpload: {getImagesCallback: GetObjects}"></div>
In the bindinghandler:
var options = ko.utils.unwrapObservable(valueAccessor()),
getImagesCallback = options.getImagesCallback;
getImagesCallback();
(This is similar to PW Kad's answer, but I think specifying a separate bindingKey to provide options to a different bindinghandler is a bad idea for a required argument, and is a pretty ugly way to do knockout bindinghandlers, compared to just passing an object to the current binding hander)
But really, if your binding handler is doing asyncronous calls, I think you're need to restructure something. Bindinghandlers, in my opinion, should be doing view logic only, not dealing with AJAX which should be in the ViewModel.
Collected from the Internet
Please contact [email protected] to delete if infringement.
Comments