首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Dojo自定义组件的属性总是默认的

Dojo自定义组件的属性总是默认的
EN

Stack Overflow用户
提问于 2014-10-08 10:32:08
回答 1查看 54关注 0票数 0

我已经编写了一个自定义组件来创建一个html按钮。自定义组件定义如下

代码语言:javascript
复制
dojo.provide("ovn.form.OvnButton") ;

require([ "dojo/_base/declare",
       "dojo/dom-construct",
       "dojo/parser",
       "dojo/ready",
       "dijit/_WidgetBase"],
       function (declare, domConstruct, parser, ready, _WidgetBase){

       return declare ("ovn.form.OvnButton",[_WidgetBase],{

            label: "unknown",            
            constructor : function(args){
                this.id = args.id;
                args.props.forEach(function(prop) {
                    if(prop.name == 'label'){
                        this.label = prop.value;
                        alert("found label " + this.label);
                    }                         
                });
                alert("from constructor " + this.label);
            },
            postMixInProperties : function(){
            },
            buildRendering : function(){

                alert("from renderer label is " + this.label);
                this.domNode = domConstruct.create("button", { innerHTML: this.label }); //domConstruct.toDom('<button>' + this.label + '</button>');
            },
            _getLabelAttr: function(){
                return this.label;
            },
            _setLabelAttr : function(label){
                alert("from set input is " + label)
                this.label = label;
            },             
            postCreate : function(){
                alert("Post create label is " + this.label);
            },
            startUP : function(){
            }
        });

});

这就是我实例化组件的方式。

代码语言:javascript
复制
var button = new ovn.form.OvnButton({
                          id:'run',
                          props:[{"name":"label","value":"Run"},{"name":"class","value":"btn"}]
                      });

在自定义组件的构造函数中,我迭代传递的数组并将其赋值给实例变量'label‘。令我惊讶的是,当我们在buildRendering函数中打印实例变量时,它仍然打印默认值而不是指定的值。

有人能解释一下为什么会这样。

FYI:我在控制台上得到以下消息序列:找到的标签运行2、构造函数未知3、呈现器标签未知4、设置输入未知5、Post创建标签未知

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-10-09 11:16:55

这是因为在小forEach函数中,this实际上指向与OvnButton对象完全不同的东西。

Javascript的this关键字在这方面非常奇怪(实际上,它与Dojo没有任何关系)。您可以在这里更多地了解它的工作原理:http://howtonode.org/what-is-this。这是Javascript的一个非常基本的概念,与其他语言不同,因此值得您花时间熟悉它。

但是有各种不同的方法可以快速解决它,所以这里有几个!

使用正则for循环而不是forEach和回调

最简单的方法可能是使用正则for循环而不是带回调的forEach。

代码语言:javascript
复制
....
// args.props.forEach(function(prop) {
for(var i = 0, l = args.props.length; i < l; i++) {
    var prop = args.props[i];    
    if(prop.name == 'label'){
        this.label = prop.value;
        alert("found label " + this.label);
    }                         
}//); <-- no longer need the closing parenthesis

这里需要注意的是,Javascript的this魔术只发生在函数调用上,所以在本例中,当我们只使用for循环时,this继续指向正确的东西。

..。或用于second的第二个thisArg参数

但也许您真的想要使用forEach。它实际上有第二个参数,通常称为thisArg。它告诉forEach确保this指向您在回调函数中选择的内容。所以你会这样做:

代码语言:javascript
复制
....
args.props.forEach(function(prop) {
            if(prop.name == 'label'){
                this.label = prop.value;
                alert("found label " + this.label);
            }                         
        }, this); // <--- notice we give forEach two arguments now,
                  //      the callback function _and_ a "thisArg" value

不过,我不太确定上面的方法在所有浏览器中都能正常运行,所以这里有另一种解决问题的方法:

..。或者使用临时的“自我”变量

我们将使一个临时变量等于this。人们通常将这样的变量称为self,但您可以任意命名它。这一点很重要:只有Javascript在回调函数中不同对待的是this关键字:

代码语言:javascript
复制
....
var self = this; //<--- we basically give `this` an alternative
                 //     name to use inside the callback.
args.props.forEach(function(prop) {
            if(prop.name == 'label'){
                self.label = prop.value; //<--- replaced `this` with `self`
                alert("found label " + self.label); //<--- here as well
            }                         
        });

..。或使用dojo/_base/lang中的hitch()

有些人不喜欢self解决方案,可能是因为他们喜欢不断地使用this来引用拥有的对象。因此,许多框架都有一个"bind“函数,它确保函数总是在特定的作用域中调用。在dojo的例子中,这个函数被称为hitch。下面是如何使用它:

代码语言:javascript
复制
require([....., "dojo/_base/lang"], function(....., DojoLang) {
    ....
    args.props.forEach(DojoLang.hitch(this, function(prop) {
            if(prop.name == 'label'){
                this.label = prop.value;
                alert("found label " + this.label);
            }                         
        }));

..。或者使用Javascript自己的bind()

Dojo和几乎所有其他框架都有一个hitch()函数。因为在Javascript中它是一个常用的概念,所以新的Javascript标准实际上引入了它自己的变体Function.prototype.bind()。你可以这样使用它:

代码语言:javascript
复制
....
args.props.forEach(function(prop) {
    if(prop.name == 'label'){
        this.label = prop.value;
        alert("found label " + this.label);
    }                         
}.bind(this));

这是一个很长的答案,一个相当小的事情,我希望这是有意义的!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26254739

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档