BorisMoore / jsviews

Interactive data-driven views, MVVM and MVP, built on top of JsRender templates
http://www.jsviews.com/#jsviews
MIT License
857 stars 130 forks source link

Deep linking and view helpers #261

Closed RaMIeL81 closed 10 years ago

RaMIeL81 commented 10 years ago

Hi Boris, i'm trying to deep observe data changes inside a view helper function with no success.Not sure about the right sintax to use. Look at this fiddle http://jsfiddle.net/YJ5Ae/2/

thanks.

BorisMoore commented 10 years ago

It's not really deep data changes you are doing - it is specifying paths programmatically.

JsViews declarative data-linking paths are defined statically. If you want a helper to be automatically refreshed by some underlying observable change, you need to specify a static path that the helper depends on.

http://jsfiddle.net/BorisMoore/YJ5Ae/4/

You can change the field from title to foo, and then change the value of foo, and it will update correctly too.

<script type="text/x-jsrender" id="languagesTemplate">
    <p> Helper 1 : {^{:~renderLanguage(languages, field)}}</p>
    <p> Helper 2 : {^{:~renderItLanguage(languages.it.title)}}</p>
    <p> Normal Link : {^{:languages.it.title}}</p>
    <p><input type="text" data-link="languages[language].title" /></p>
    <p><input type="text" data-link="languages[language].foo" /></p>
    <p><input type="text" data-link="field" /></p>
</script>
</head>
<body><div id="container"></div>

<script type='text/javascript'>

function getCurrentLang(){
    return data.language;
}

function renderLanguage(obj, field){
    return obj[getCurrentLang()][field];
}

var data = {
    languages : {
        it : {
            foo : 'xx',
            title : 'Titolo'
        },
        en : {
            foo : 'dd',
            title : 'Title'
        }
    },
    field: 'title',
    language: "it"
};

renderLanguage.depends = "languages." + getCurrentLang() + ".*";

$.templates({
    languages : "#languagesTemplate"
});

$.views.helpers({
    renderLanguage : renderLanguage,
    renderItLanguage : function(data){
        return 'this is the \'it\' title : '+data;
    }
});

$.link.languages('#container',data);

</script>

Note that we declare that it depends on languages." + getCurrentLang() + ".*" - which corresponds to "languages.it.*" - so it is listening to all changes (any field) on the it object. But if you change the current language then you will no longer be listening to the right object.

So if you want to be able to dynamically change the current language, you will need to use observe or observeAll to declare your own handlers. e.g. Define a custom tag {^{renderLanguage field ^language=language/}} and when language changes, make it unobserve the previous language and observe the new one. This is a more advanced scenario...

BorisMoore commented 10 years ago

Closing - since question covered.