Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于控件创建时的各来源的参数的优先级 #7

Closed
otakustay opened this issue Mar 28, 2013 · 8 comments
Closed

关于控件创建时的各来源的参数的优先级 #7

otakustay opened this issue Mar 28, 2013 · 8 comments
Labels

Comments

@otakustay
Copy link
Member

比如说我们new一个控件的时候吧,会传一个options对象,这个对象里可能有个main属性提供HTML元素,这时就有问题了。

有一些参数,会从main上去提取,但同时options对象里又有同名的参数,这里的优先级需要讨论,典型的如下代码:

var a = document.createElement('a');
a.href = 'http://www.baidu.com';
document.body.appendChild(a);
var link = new Link({ main: a, href: 'http://www.google.com' });
link.render();

那么,这个link控件的href到底应该是百度还是Google呢?

同样的问题也出在从HTML解析出控件的时候:

<a href="http://www.baidu.com"
    data-ui-type="Link"
    data-ui-href="http://www.google.com">
    This is a link
</a>
@errorrik
Copy link

原则

这个问题,我整理标准草案的时候漏写了,是我的疏忽。

我的设想是:永远是用户通过JS传的参数优先,无论是new时还是运行中set时

实现

对于构造函数,初始化options的时候,如果满足下面条件,才从main上读:

1.属性不存在
2. 有main时

@otakustay
Copy link
Member Author

简单来说就是

  1. 默认值
  2. main上拿来的值
  3. 构造函数传进来的值

然后按优先级由低到高给合在一起,再进行后续的逻辑对吧?

那么我建议控件里加一个抽象方法getOptionsFromMain,然后helper.init来完成这件事

@errorrik
Copy link

然后按优先级由低到高给合在一起,再进行后续的逻辑对吧?

对的,我也是这么觉得。

我的建议是:增加个initOptions(control, options, defaultOptions)吧,在里面做getOptionsFromMain呗。helper.init现在是存在的,我觉得可以helper.init调用initOptions

@otakustay
Copy link
Member Author

可以,但initOptions这个方法是返回options还是直接往自己身上加了?如果是前者,这名字不适合……

@errorrik
Copy link

当然是后者咯

@otakustay
Copy link
Member Author

我重新整理了一下,其实一共是有4个层级的,优先级 从低到高 依次是:

  1. 默认的选项
  2. main上取得的部分选项,如href之类的
  3. 构造函数传进来的选项
  4. main上取得的只读的固定的选项,如modetagName之类的

最后一个有点特殊,因为有些属性是有main了以后就固定了的,比如<input>元素的type属性,这些东西是不能被构造函数传进来的参数所覆盖的。

我写了一下Label,大概是这样一个逻辑, @errorrik 看看对不对:

Label.prototype.initOptions = function (options) {
    options = options || {};

    var defaults = {
        tagName: 'span'
    };
    if (options.main) {
        var extracted = {
            content: options.main.innerHTML
        };
        require('./lib').extend(defaults, extracted);
    }
    require('./lib').extend(defaults, options);
    // 如果已经有对应的元素,则`tagName`是只读的不可被覆盖
    if (options.main) {
        defaults.tagName = options.main.nodeName.toLowerCase();
    }
    this.setProperties(defaults);
};

@errorrik
Copy link

嗯,没问题,4的情况貌似很少会出现。

@otakustay
Copy link
Member Author

关于构建时的顺序已经实现,按new -> createMain -> initOptions来,initOptions中已经不需要options.main的判断了

3610cn added a commit that referenced this issue Jul 20, 2015
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants