This is a migrated thread and some comments may be shown as answers.

Custom binding and complicated binding path

19 Answers 735 Views
MVVM
This is a migrated thread and some comments may be shown as answers.
Nik
Top achievements
Rank 1
Nik asked on 13 Apr 2012, 10:07 AM
Hello,
I'm trying to create custom binding for CSS classes with switching by condition because the "style" binding isn't useful for my case. My cssClass binding uses "path with params " like "style" and "attr" bindings:

data-bind="cssClass: {condition: isEnabled, class1: style-red, class2: style-blue }"

In docs I see one example  this.bindings["slide"].get() for simple path like data-bind:"slide:isEnabled"
What is the legit solution for processing this types of bindings (with complicated pathes)?

Please, take a look on my realisation CSS custom binding example 
It works on page load but not works when isEnabled updated. I suspect that this behavior is due to the fact that I did not cal .get() function. But when I call that function I've got this error message: Uncaught TypeError: Object #<Object> has no method 'charAt'.

19 Answers, 1 is accepted

Sort by
0
Luc
Top achievements
Rank 1
answered on 18 Apr 2012, 02:48 AM
I too would like to know how to create those "complex" bindings, as what I have tried so far doesn't work.
Thanks
0
Accepted
Rosen
Telerik team
answered on 18 Apr 2012, 07:49 AM
Hello,

I'm afraid that such bindings declaration is currently not supported. As a workaround in this specific case you may use similar to the following approach:

Regards,
Rosen
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Nik
Top achievements
Rank 1
answered on 18 Apr 2012, 08:07 AM
Thank you, it's suitable for me.
0
Luc
Top achievements
Rank 1
answered on 18 Apr 2012, 11:06 AM
Thanks Rosen, this works fine.

The only remaining problem for me is when using this within a template. I think this is related to my other question here: http://www.kendoui.com//forums/framework/mvvm/custom-binding-not-working-in-templates.aspx

What it seems to be is that when used within a template, such bindings look at the currently iterated object which is not the ViewModel itself.

For example, if I have such a ViewModel:

var vm = new kendo.observable({
    products: [{name: 'Banana'}, {name: 'Apple'}, {name: 'Orange'}],
    isEnabled: true //would be a function in real life
    goToFolder: function() {...} // some function
});

and then use a source binding as this:

<ul data-template="product-template" data-bind="source: products"></ul>
<script id="product-template" type="text/x-kendo-template">
<li data-bind="click: goToFolder, cssClass: isEnabled, text: name" data-enabled-class="style-red" data-disabled-class="style-blue"></li>
</script>

the cssClass binding will look for the "isEnabled" property on the product object. I'd like it to look at the "parent" ViewModel instead. How could this be accomplished ?

On the other hand, the click binding does use the goToFolder function on the ViewModel, so I'm thinking it's possible to access the ViewModel, but I can't figure out how.

Thanks

EDIT: I'm using Kendo UI Complete v2012.1.406
0
Rosen
Telerik team
answered on 18 Apr 2012, 04:19 PM
Hi Luc,

As you are using an internal build, you may be able to use the parent method of the ObservableObject/ObservableArray to achieve similar to the desired behavior:

<li data-bind="click: goToFolder, cssClass: parent().parent().isEnabled, text: name" data-enabled-class="style-red" data-disabled-class="style-blue"></li>

However, note that as this is an internal build the behavior may change in the feature.Greetings,
Rosen
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Luc
Top achievements
Rank 1
answered on 18 Apr 2012, 04:45 PM
Rosen,

This seems to work so far, thanks.

I didn't know such syntax was allowed. Is that documented somewhere, or is it just a beta feature ?

Regards
0
Rosen
Telerik team
answered on 18 Apr 2012, 05:13 PM
Hi Luc,

This is more of undocumented workaround, which as I have mentioned may not function in feature versions.

Regards,
Rosen
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Luc
Top achievements
Rank 1
answered on 18 Apr 2012, 05:45 PM
Rosen,

Please believe me when I say I appreciate the efforts that the KendoUI team puts into helping us, but I hope you'll understand that as a developer, I can't rely on undocumented features. The reason is quite simple, as you put it yourself, it might not work in the future. I need features that won't break my code down the road.

Now, if I may go back to the reason why I have to jump through so many hoops to get this working is simply that kendoUI's bindings don't yet offer a css binding.

I know there is a style binding, but I refuse to use this as it places style information in my code and this is not where it belongs. Style should go in css files, and we should be able to conditionally apply style to our bound elements.

This is definitely a major concern for me, and for many others I'd think.

Regards
0
Rosen
Telerik team
answered on 19 Apr 2012, 11:33 AM
Hello Luc,

Indeed, the MVVM class binding is currently not supported. If you would like to be included in a future version of the library, you may submit your idea here.

All the best,
Rosen
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
Luc
Top achievements
Rank 1
answered on 19 Apr 2012, 02:08 PM
Rosen,

I just entered the wish on the UserVoice site.

I know that KendoUI MVVM was only recently released, but I sure hope it will mature quickly to become at least at par with knockoutjs.

Regards
0
Luc
Top achievements
Rank 1
answered on 19 Apr 2012, 05:47 PM
Rosen,

Out of curiosity I implemented the parent().parent().isEnabled workaround, and at first I thought it did work but now I realise it only works the first time the page is loaded.

Debugging shows that the refresh method of the binding is not called when the "isEnabled" value on my ObservableObject changes, even though I made sure to use the set() method to modify it.

I just thought I'd let you know.
0
sitefinitysteve
Top achievements
Rank 2
Iron
Veteran
answered on 08 May 2012, 04:23 PM
Where can I get this .parent() workaround version of .web?
0
Rosen
Telerik team
answered on 08 May 2012, 04:49 PM
Hello Steve,

The parent property is available in the latest internal build.

Regards,
Rosen
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
sitefinitysteve
Top achievements
Rank 2
Iron
Veteran
answered on 08 May 2012, 05:12 PM
v2012.1.503?

I have a problem with that build...it's throwing this error
"((f.event.special[s.origType] || {}).handle || s.handler).apply is not a function" in jquery.min 1.7.2

I have an element inside of a array template bound to this
data-bind="click: addItem"

Where addItem is a function in the viewModel
viewModel = kendo.observable({
        addItem: function (campus) {
            this.selectedCampus = campus;
            openAddNewWindow();
        }
    });
 
$.extend(viewModel, kendo.observable(data));

So "addItem" exists I guess technically in the parent()...so if I change it to
data-bind="click: parent().addItem"
I get the same error....so for giggles I change it to
data-bind="click: parent().parent().addItem"
...and it tells me parent() isn't a function

  • Am I missing something?  Like the addItem viewModel function itself never gets called "When defined inside a template"
0
Rosen
Telerik team
answered on 09 May 2012, 08:27 AM
Hello Steve,

I'm afraid that this code will not work as you are extending the one viewModel  with the other, however this will not set the correct parents. Instead of using extend you may loop over the other objects fields and add them to the ViewModel instance: 

$(document).ready(function() {
    var data = { items: [{foo: "foo"}] };
     
    var viewModel = kendo.observable({
        addItem: function() {
            alert("Item is clicked");
        }
    });
     
    for (var field in data) {
        viewModel.set(field, data[field]);
    }
     
    kendo.bind($("#container"), viewModel);
});​

However, note that this will not work as expected with the current internal build and you should wait for the next one.
All the best,
Rosen
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
sitefinitysteve
Top achievements
Rank 2
Iron
Veteran
answered on 09 May 2012, 01:11 PM
@Rosen
  I would like to respectfully say no to this solution :)  You guys can come up with better...maybe a utility method or something.

Here's my model...it's more than a single array with "foo".  Part of the idea of MVVM is to help save time and code, not have my model be a giant nested loop to re-set values.  Atanas was the one who told me to use $.extend in the first place.

var coredata = {
    "BlockID": 14,
    "ClerkshipID": 1,
    "Cohort": 2013,
    "Clerkship": "Anesthesiology",
    "IsSelective": false,
    "StartDate": "2011-12-05T00:00:00",
    "EndDate": "2011-12-19T00:00:00",
    "Campuses": [{
        "CampusID": 0,
        "Campus": "Hamilton",
        "Released": true,
        "AvailableToHamilton": false,
        "Rotations": [{
            "RotationID": 6,
            "Rotation": "Anesthesiology",
            "Sites": [{
                "SiteID": 2,
                "Site": "Chedoke Hospital",
                "Min": 1,
                "Max": 2},
            {
                "SiteID": 11,
                "Site": "Hamilton General Hospital",
                "Min": 0,
                "Max": 2},
            {
                "SiteID": 45,
                "Site": "Hamilton Health Sciences",
                "Min": 1,
                "Max": 4}]}]},
    {
        "CampusID": 1,
        "Campus": "Waterloo",
        "Released": true,
        "AvailableToHamilton": false,
        "Rotations": [{
            "RotationID": 6,
            "Rotation": "Anesthesiology",
            "Sites": [{
                "SiteID": 47,
                "Site": "Kitchener-Waterloo",
                "Min": 3,
                "Max": 3}]}]},
    {
        "CampusID": 2,
        "Campus": "Niagara",
        "Released": false,
        "AvailableToHamilton": false,
        "Rotations": []}],
    "AllReleased": false
};
0
Rosen
Telerik team
answered on 09 May 2012, 02:14 PM
Hi Steve,

If you take a more close look at the ObservebleObject's set method, you may notice that it support setting objects thus it will make the whole passed in object observable. Therefore, the code from my previous post will work with the object you have shown as it is without modifications.

Regards,
Rosen
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
0
sitefinitysteve
Top achievements
Rank 2
Iron
Veteran
answered on 09 May 2012, 02:18 PM
OH FANTASTIC!...I mean still would be nice to have a helper instead of having to do a loop (essentially every time for me since I'll always bind to remote JSON).

Perhaps
viewModel.load(data)
?

When can you get this internal build out?...
0
Rosen
Telerik team
answered on 10 May 2012, 12:19 PM
Hello Steve,

Most probably there will be a service pack available in the next week or two.

Greetings,
Rosen
the Telerik team
Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
Tags
MVVM
Asked by
Nik
Top achievements
Rank 1
Answers by
Luc
Top achievements
Rank 1
Rosen
Telerik team
Nik
Top achievements
Rank 1
sitefinitysteve
Top achievements
Rank 2
Iron
Veteran
Share this question
or