如何挂钩到小部件中模型的更改

How to hook into a change in the model in a widget

我正在尝试响应小部件中模型属性之一的更改。需要明确的是,当 属性 的值发生变化时,我想要 运行 一些代码来对变化做出反应。在父小部件中,我有一个日期选择器,它可以更改模型中的日期。

我无法让自定义 setter 被调用 _setParentPropertyAttr...

如果我将其包含在我的小部件中

<span data-dojo-type="dojox/mvc/Output" data-dojo-props="value: at(rel:, 'ParentProperty')">

效果很好。更改日期选择器会将当前值输出到页面。因此,当模型中的日期发生变化时,我可以将值 属性 提供给输出小部件。但是我需要做的(我认为)是在日期选择器更改值时在模型中提供带有日期 属性 的自定义 属性。

我知道这个问题有点含糊,但我无法提供代码,因为它是专有的。

我试图通过在我的小部件中手动设置 属性 来解决问题:

myProperty:0,
...
constructor
...
_setMyPropertyAttr: function(value):
{
    console.log("setting myproperty");
}

....
this.set('myProperty', 5);
....

但这也不起作用。

如果您在小部件中设置 属性 是否不会调用自定义 setter?

我有点挣扎,因为没有那么多 dojo 示例,非常感谢任何帮助。

考虑在您的小部件上使用自定义 setter,您可以在其中添加自定义逻辑。

自定义 setter 在您的小部件上的定义示例:

     _setOpenAttr: function(/*Boolean*/ open){
         // execute some custom logic here
         this._set("open", open);
     }

在您的小部件上设置 属性 的示例:

widgetRef.set('open', true);

或者您可以考虑使用 dojo/store/Observable

dojo/store/Observable 添加对数据更改通知支持的存储包装器。

您可以在以下link阅读更多相关信息:

https://dojotoolkit.org/reference-guide/1.10/dojo/store/Observable.html

您可以绑定一个事件,以便在小部件的 属性 为 set/update 时调用,或者您甚至可以使用 watch 来执行此操作。
但这只适用于 set 函数,使用 someWidget.someProperty = 5; 将不起作用。
让我向您展示如何 dojo 做到这一点。关于魔术 setter 和吸气剂 is explained here 的基础知识。

_set: function(/*String*/ name, /*anything*/ value){
    // summary:
    //      Helper function to set new value for specified property, and call handlers
    //      registered with watch() if the value has changed.
    var oldValue = this[name];
    this[name] = value;
    if(this._created && !isEqual(oldValue, value)){
        if(this._watchCallbacks){
            this._watchCallbacks(name, oldValue, value);
        }
        this.emit("attrmodified-" + name, {
            detail: {
                prevValue: oldValue,
                newValue: value
            }
        });
    }
}

这段代码来自 dijit/_WidgetBase_set 函数是 dojo 在调用 set 之后调用的函数,也是它最终设置 属性 值 this[name] = value;,如您所见,它 emit 一个将被称为 attrmodified-propertyName 的事件,也称为 watchCallbacks

例如,如果在某个地方,我们有这个:

on(someWidget, 'attrmodified-myproperty', function(){
    console.log(someWidget.get('myProperty'));
});

然后我们使用:

someWidget.set('myProperty', 'Hello World!');

事件将被触发。请注意 someWidget.myProperty = 'Hello World!' 不会触发事件注册。另请注意,如果在我们的小部件中我们定义了魔法 setter:

_setMyPropertyAttr: function(value) {
    //do something here with value
    // do more or less with other logic

    //but some where within this function we need to cal "_set"
    this._set('myProperty', value);
}

不调用 _set,魔法就不会发生。

正如我一开始所说的,我们也可以使用watch

someWidget.watch('myProperty', function(){
    console.log(someWidget.get('myProperty'));
});

请注意,我们可以在同一小部件​​中注册此事件或 watch 功能。

此外,作为一个加号,在创建小部件时只需在构造函数对象参数中传递 属性 名称即可触发魔法 setter,这也适用于声明性语法,因为示例:

var someWidget = new MyWidget({
    'myProperty': 'Hello World!!'
});

<div data-dojo-type="MyWidget" data-dojo-props="myProperty: 'Hello World!!'"></div>

两者都将触发对 _setMyPropertyAttr 的调用(如果存在),否则 dojo 将在不存在的情况下使用魔法 setter

希望对您有所帮助

如果解决了问题。如果我在模型上设置一个手表,我就可以检查手表功能中的个别属性是否发生了变化。我知道这会很简单!