Opened 5 years ago

Closed 5 years ago

#18311 closed defect (worksforme)

"dojo/Stateful" set() calls getter too

Reported by: dojonovice@… Owned by:
Priority: undecided Milestone: tbd
Component: General Version: 1.10.1
Keywords: Cc:
Blocked By: Blocking:

Description

If I use "dojo/Stateful"

                        _summarySetter: function (value) {
                          this.summary = value;                           
                          this.display("set", value);                           
                        },
                        _summaryGetter: function () {
                            this.display("get", this.summary);
                        },
                        display: function (action, value) {
                            console.log(action + ": " + value);
                        }

and call set() method

var module = new Module();
module.set("summary", "testing value");

Getter is called too. What is wrong in my code or is it a bug?

Modul "dijit/_WidgetBase" works fine, only setter is called.

Change History (6)

comment:1 Changed 5 years ago by dylan

Are you sure the getter isn't being called when you first initialize the constructor? Is get being called repeatedly for you each time you call set ?

comment:2 Changed 5 years ago by ben hockey

setters and getters are not the same between dojo/Stateful and dijit/_WidgetBase. the getter is definitely called as part of set (https://github.com/dojo/dojo/blob/5904b65a6b23ec3192290bfa6f761ba2d26179dc/Stateful.js#L116) when using dojo/Stateful - this is working as intended so that the old value can be passed to the watchers.

dylan - do you think it should be different? it's likely not something that can be changed in dojo 1.x now.

Last edited 5 years ago by ben hockey (previous) (diff)

comment:3 Changed 5 years ago by dojonovice@…

Testcase - module (Module.js)

define(["dojo/Stateful", "dojo/_base/declare"],
        function (Stateful, declare) {
            return declare([Stateful],
                    {
                        summary : "",
                        constructor: function () {

                        },
                        _summarySetter: function (value) {
                            this.summary = value;
                            this.display("set", value);
                        },
                        _summaryGetter: function () {
                            this.display("get", this.summary);
                        },
                        display: function (action, value) {
                            console.log(action + ": " + value);
                            // do something 
                        }
                    });
        }); 

require

         require(["Module", "dojo/ready"], function (Module, ready) {
                ready(function () {

                    var module = new Module();
                    module.set("summary", "test1");
                    module.set("summary", "test2");
                    module.set("summary", "test3");
                    // module.get("summary");

                })

You can test it. My output:

get: set: test1 get: test1 set: test2 get: test2 set: test3

What is wrong in my code? I don't expect get info when using set.

comment:4 Changed 5 years ago by ben hockey

nothing is wrong with your code. it works exactly how dojo/Stateful has been written to work.

while it might not be what you want, it's working exactly how it's been designed to work. if you need to change the behaviour, you can do like what dijit does and redefine/extend a large portion of the behaviour to match your desires.

the only reason i haven't closed this ticket already is in case dylan thinks the current behaviour is something that should be reconsidered. apart from that, i see no reason to keep this ticket open.

comment:5 Changed 5 years ago by dojonovice@…

Why is getter invoked when I invoke setter? This is what I don't understand.

comment:6 Changed 5 years ago by ben hockey

Resolution: worksforme
Status: newclosed

dojo/Stateful provides 3 methods as part of its public API - set, get, and watch. when someone registers a handler via watch, that handler will be called whenever relevant properties are set. the handler registered via watch will be called with 3 parameters:

  1. the name of the property which was changed
  2. the previous value of the property
  3. the new value of the property

using obj.set('prop', value); as an example:

  1. the name of the property comes from the call to set - it will be 'prop'
  2. the previous value comes from calling the getter for 'prop'
  3. the new value comes from the call to set - it will be value

this is why the getter is called as part of calling the setter - it is for the sake of the handles registered via watch so that the previous value can be obtained to pass to them.

Note: See TracTickets for help on using tickets.