Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Refreshing Dojo MVC Groups on model change doesn't work for complex objects

As shown below, I have a dummy memory store which returns a complex object. I would like to bind this complex object to the form. Because it's a complex object, I am binding the object through two MVC groups. The problem happens when the model is refreshed (through the "Fetch" button). The outer MVC group is refreshed, but the inner one is not. It works only if I manually re-set the target property of the inner MVC group:

dijit.byId('sub-group').set('target', model.prop7);

Is there any other, better way to do this?

<script type="text/javascript">
    // Create dummy store
    var store;
    require(['dojo/store/Memory'], function(Memory) {
        store = new Memory({
            data: [{
                id: 1,
                prop1: 'prop 1 value',
                prop2: 'WA',
                prop7: {
                    prop8: 'prop 4 value',
                    prop9: 'prop 5 value'
                }
            }]
        });
    });

    // Create model for MVC
    var model;
    require([
        'dojo/dom',
        "dojo/parser",
        "dojo/Stateful",
        "dojo/domReady!"
    ], function (dom, parser, Stateful) {
        model = new Stateful();
    });

</script>

<button data-dojo-type="dijit/form/Button" data-dojo-props="iconClass: 'dijitIconDatabase'">
    <script type="dojo/on" data-dojo-event="click">
        var data = store.get(1);

        model.set(data);

        //dijit.byId('sub-group').set('target', model.prop7);
    </script>

    Fetch
</button>


<form data-dojo-type="dijit/form/Form" id="form" data-dojo-type="dojox/mvc/Group" data-dojo-props="target: model">
    <script type="dojo/require">at: "dojox/mvc/at"</script>

    <div class="row">
        <label for="text">Text:</label>
        <input id="text" data-dojo-type="dijit/form/ValidationTextBox" required="true" data-dojo-props="value: at('rel:', 'prop1')"/>
    </div>

    <div class="row" id="sub-group" data-dojo-type="dojox/mvc/Group" data-dojo-props="target: model.prop7">
        <label for="text2">Text 2:</label>
        <input id="text2" data-dojo-type="dijit/form/ValidationTextBox" required="true" data-dojo-props="value: at('rel:', 'prop8')"/>
    </div>
</form>
like image 247
Ariod Avatar asked Nov 18 '25 03:11

Ariod


1 Answers

Several things I can say are:

  • In general, you need to use dojox/mvc/at to make a widget react to change in model. dojox/mvc/Group is no exception for that.
  • Dojo does not allow you to put two data-dojo-type to one element. You may want to consider data-dojo-mixins.
  • To make a data model of nested object, you'll need to use dojox/mvc/getStateful. dojox/mvc/StatefulModel has been superseded by dojox/mvc/getStateful and dojox/mvc/StoreRefController as of 1.8 release.

Here’s a sample code for similar use case:

<!DOCTYPE html>
<html>
    <head>
        <link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.1/dojo/resources/dojo.css" />
        <link id="themeStyles" rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.1/dijit/themes/claro/claro.css" />
        <script type="text/javascript" src="//ajax.googleapis.com/ajax/libs/dojo/1.10.1/dojo/dojo.js" data-dojo-config="parseOnLoad: 0, async: 1"></script>
        <script type="text/javascript">
            require([
                "dojo/parser",
                "dojo/store/Memory",
                "dojox/mvc/getStateful"
            ], function(parser, Memory, getStateful){
                model = getStateful({});
                store = new Memory({
                    data: [{
                        id: "mydata",
                        prop1stLevel: "Value of 1st level property",
                        group2ndLevel: {
                            prop2ndLevel: "Value of 2nd level property"
                        }
                    }]
                });
                parser.parse();
            });
        </script>
    </head>
    <body class="claro">
        <script type="dojo/require">at: "dojox/mvc/at"</script>
        <button data-dojo-type="dijit/form/Button" data-dojo-props="iconClass: 'dijitIconDatabase'">
            <script type="dojo/on" data-dojo-event="click">
                require(["dojox/mvc/getStateful"], function(getStateful){
                    model.set("group1stLevel", getStateful(store.get("mydata")));
                });
            </script>
            Fetch
        </button>
        <form id="form" data-dojo-type="dijit/form/Form" data-dojo-mixins="dojox/mvc/Group" data-dojo-props="target: at(model, 'group1stLevel')">
            <div class="row">
                <label for="1st-level">1st level:</label>
                <input id="1st-level" data-dojo-type="dijit/form/ValidationTextBox" required="true" data-dojo-props="value: at('rel:', 'prop1stLevel')"/>
            </div>
            <div class="row" id="sub-group" data-dojo-type="dojox/mvc/Group" data-dojo-props="target: at('rel:', 'group2ndLevel')">
                <label for="2nd-level">2nd level:</label>
                <input id="2nd-level" data-dojo-type="dijit/form/ValidationTextBox" required="true" data-dojo-props="value: at('rel:', 'prop2ndLevel')"/>
            </div>
        </form>
    </body>
</html>

Hope this helps.

Best, - Akira

like image 187
asudoh Avatar answered Nov 20 '25 19:11

asudoh



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!