2

I'm using the i18next library alongside of kendo and have had no issues getting things working as expected in the Kendo UI Web portion of my app, but the Mobile is a different story. I thought that I could call my i18n function from the init function and have it populate the "data-i18n" in my templates' attributes with no problem... but it seems like you cannot access any of the view elements until after the view is completely built/bound... So I tried putting the i18n code in a "DataBound" event for the ListView which does work, but that seems like a lot of unnecessary code execution every time the list is rendered/refreshed.

Thoughts on how to better do this? I haven't even started down the path of localizing the Layouts because of this.

Here's my template for the view Itself:

<div id="dashboard-meeting" data-role="view" data-model="dashViewModel" data-bind="events:{init:meetingListInit,show:meetingListShow}" data-layout="drawer-layout" data-title="By Meeting"> <ul id="meeting-list" class="meetingList"></ul> <div class="no-data" style="display:none;">No Data</div> </div>

This is the row item template for the list...

<script type="script/x-kendo-template" id="meeting-item">
    <a data-item-id="#=meetingID#" href="\#meeting-details?id=#=meetingID#" data-transition="slide:left">
    <h3 class="time">#= startTime #</h3>
    <h3 class="counts"><span class="hc" data-i18n="dashboard.headCountText"></span>: #=headCount# | Total: #=totalCount#</h3>
    <h2>#=meetingName#</h2>
    </a>
</script>

And here is my viewModel:

    var dashViewModel = kendo.observable({
    headCountText : "Head Count",
    meetingListInit : function(e){
        var meetingList = $("#meeting-list").kendoMobileListView({
            dataSource: bymeetingData,
            pullToRefresh: true,
            template: $('#meeting-item').html(),
            dataBound: function(e){
                console.log("Data Bound");
                i18n.init(lang_options).done(function() {
                    //dashViewModel.set("headCountText", $.t("dashboard.headCount"));
                    //console.log("this list init'd" , $.t("dashboard.headCount"))
                    //$("#meeting-list").i18n();
                    $(".hc").text($.t("dashboard.headCount"));
                });
            }
        }).data("kendoMobileListView");
    },
    meetingListShow : function(e){
        //bymeetingData.read();
        $("#meeting-list").data("kendoMobileListView").refresh();
    }
});

As you can see in my comments in my init code I even tried to bind the text of the list item elements for "head count" to a data model text string that is localized via the init function. But that wouldn't bind, so I gave up on that and went this route.

demongolem
  • 9,474
  • 36
  • 90
  • 105
btbJosh
  • 305
  • 2
  • 12

1 Answers1

1

I believe the MVVM binding and initialization actually happens before the view init and show events, so you could potentially change the i18n stuff in either of those events.


You could actually just use the text MVVM binder to handle i18n instead of using another library like i18next.

<span data-bind="text: strings.hello"></span>

and my ViewModel has a "strings" hash (that is actually loaded at startup as JSON)

var english = {
    hello: "Hello"
};

var spanish = {
    hello: "Hola"
};

var viewModel = kendo.observable({
    strings: english
});

function enEspanolPorFavor() {
    viewModel.set("strings", spanish);
}

The viewModel.set("strings", ...) would notify the text binders that they need to update for a language change.

CodingWithSpike
  • 42,906
  • 18
  • 101
  • 138
  • Hey @CodingWithSpike, I was actually scouring your website as it's full of great Kendo stuff. But I'm pretty sure I've tried a different version of what you're suggesting (albeit yours is simpler). I wasn't able to get my meeting-item template to data-bind="text:headCount" to the text in my view model for some reason... Any thoughts as to why that won't work?? – btbJosh Sep 09 '14 at 16:25
  • I suspect that is due to your use of `.kendoMobileListView()` to initialize the widget, instead of doing it declaratively with `data-role="listview"`. I believe that if a widget isn't MVVM bound/initialized, then its child elements don't get MVVM bound either. – CodingWithSpike Sep 09 '14 at 16:32
  • Ah! I will go that route and try some things using that declarative approach and report back. – btbJosh Sep 09 '14 at 16:34
  • For some reason I still cannot bind that text to that item template element. I don't know what I'm doing wrong. Are you sure that even works? I've really not seen any demos on the kendo site that even does that. – btbJosh Sep 09 '14 at 19:33
  • I just remembered why I didn't go the MVVM declarative route. I couldn't get pull parameters working without initializing the widget via the javascript function. `.kendoMobileListView()` – btbJosh Sep 09 '14 at 20:27
  • The only way I can get the child template element to bind is to call `kendo.bind(listview, dataViewModel)` from within either the dataBound event of the listview itself (which seems like a bad idea) or from the afterShow event which is also bad because of the delay. I would love to implement your solution and drop the extra library, but If I can't get it to bind to a text string at init time then I'm no further along. This is pretty frustrating. – btbJosh Sep 09 '14 at 21:43
  • By "pull parameters" do you mean `pullToRefresh`? If you are able to make a jsFiddle or jsBin or whatever to reproduce this, then I can try to take a look at it. – CodingWithSpike Sep 09 '14 at 23:37
  • Yes. I have to pass a meeting ID to my datasource upon refresh. And as far as I can tell, you can't do that within the declarative approach. Which makes it two problems and not just one. The other being the child element binding not working in either approach. I will try a jsbin and see if I can get something to show you. – btbJosh Sep 10 '14 at 13:26
  • I cant get kendo to work in JSBin for the life of me. I hate my life. This is my broken bin http://jsbin.com/dininolexeda/2/edit – btbJosh Sep 10 '14 at 16:18
  • Updated your jsbin: http://jsbin.com/dininolexeda/3/edit?html,js,output also a bit of a shameless plug; I have been trying to set aside some time to be available on CodeMentor if you need further mentoring or project help: https://www.codementor.io/codingwithspike – CodingWithSpike Sep 10 '14 at 17:33
  • Thanks for picking that apart. I was hoping to discover why I couldn't bind to the text string within my viewModel as it was. But I will attempt to just set things up as you have them here. Thanks again @CodingWithSpike – btbJosh Sep 10 '14 at 18:38
  • Ah, one more question. In this method of localizing strings, how do you recommend swapping out the "view-title" value so that I can localize my view titles? – btbJosh Sep 10 '14 at 19:25
  • Aha. Didn't realize there was a `e.view.options.title` available. Got it! – btbJosh Sep 10 '14 at 19:31