Git Product home page Git Product logo

Comments (15)

otakustay avatar otakustay commented on August 25, 2024

参见现在Tree的设计,提供以下方法:

  • expandNode({string} id, {Array.<Object>} children):展开某个节点,如果children不给,则自己去datasource里找或用已经创建过的子树
  • collapseNode({string} id, {boolean} removeChild):收起某个节点,如果removeChildtrue ,则把子树的DOM节点删掉

提供TreeStrategy来支持树的交互,Tree默认在点击后只管发出expandcollapse事件,TreeStrategy监听这2个事件,反调用expandNode / collapseNode来实现树的收缩。

如果是远程数据,则在expand事件中,先调用indicateNodeLoading显示加载状态,有了数据再用expandNode填充即可

这样实现的Tree才300行左右的代码,还是很顺眼的

from esui.

errorrik avatar errorrik commented on August 25, 2024

这个抽象是一个比较原装的抽象了,看起来基本能解决所有树的交互和数据装载。

但还有几个问题:

  1. TreeDatasource调用fillNode,听起来很奇怪。我理解这个抽象,我指的是命名,这货不应该是datasource。
  2. fillNode和emptyNode,能简化成1个不
  3. expand时,如果想要打开里面所有的子节点,会不会有问题。或者,默认打开所有子节点
  4. 默认的node打开关闭逻辑,应该有一个的吧

还有,我理解,对用户来讲,初始化的时候传入一个datasource是数据,直接什么都不干,所有交互都应该有了吧。对应上面问题种的4。

from esui.

otakustay avatar otakustay commented on August 25, 2024
  1. 实现代码里被我命名为TreeStrategy了,但感觉TreePolicy更合适,总之是用于 描述树进行交互和数据处理和策略 的一个对象
  2. 现在成了expandNodecollapseNode了,感觉不能简化成一个,有可能一个节点,因为一些特别的原因,确定它的子节点都被删了,但它本身是展开状态的
  3. expand时现在啥也不干,如果要打开所有子节点,TreeStrategy可以找当前nodechildren,一个一个再调用expandNode打开来,然后深度到最下面为止。虽然这样看上去性能不怎么样,但其实控件本身来处理全打开这事,估计也是这方法,不大会用直接刷掉HTML的方法
  4. 默认的node打开关闭逻辑放在TreeStrategy实现里了,就是把children塞进去

from esui.

errorrik avatar errorrik commented on August 25, 2024

我再想想想

from esui.

AKIo0O avatar AKIo0O commented on August 25, 2024

我觉得在节点上加上一些属性。
类似data-url表明当前节点是否远程数据。
触发事件的时候get这个url的数据,然后render子节点。
渲染完了该节点的data-urlnone

引入TreeDatasource的概念就比较复杂了。

from esui.

otakustay avatar otakustay commented on August 25, 2024
  • 所有的DOM都是控件管理的,非控件的代码不应该访问控件控制的DOM
  • 是否远程数据是由控件的使用方决定的

因此,在控件使用方 无法往节点(DOM)上加属性 的前提下, 表示是否远程数据 得从数据的层面上来想办法。

但树的数据源是一个普通的对象,这个由E-JSON(ECOM-JSON)标准定义,且使用普通对象作为数据源有利于业务的编码,可以直接把XMLHTTPRequest请求返回的内容丢到树上。

如果让树的数据源datasource属性来表达 是否远程数据 这一概念,则要求数据源对象上有url之类的一堆配置。而现在这个设计,无非是希望原来的datasource对象不要动,把url等配置抽到另一个对象上,就是这里说的TreeDatasourceTreeStrategy,用2个对象的组合来表达一个树的信息。

from esui.

AKIo0O avatar AKIo0O commented on August 25, 2024

我的思路是通过配置DOM的属性来控制控件的行为。使用方对配置DOM应该比写控件行为要简单吧。这种想法是否合适

from esui.

otakustay avatar otakustay commented on August 25, 2024

关键在于esui从一开始就没有设计任何让使用方可以接触到DOM的接口,比如DOM元素的id规则是私有的,DOM创建是通过拼HTML(为了性能)的,并不会在每个元素创建时给一个事件,所有的事件里不得包含任何DOM对象,仅提供id之类的标识来做交互。

因此虽然可能使用方配置DOM会简单些,但整个体系与此相悖,无法提供此类的支持。

另外,如果抛开Tree这一个环节来看,从框架整体上来讲,DOM的配置在遇到复杂数据结构或需要函数作为配置项的时候,会无能为力。因此如果使用DOM进行配置,必然会再次遇到需要用非DOM来解决的地方,这就极易导致分裂,如同一个配置项,DOM可以解决代码也可以解决,控件A选择了DOM,控件B选择了代码,使用者就很难用一种惯性思维来使用这套控件,反而产生负面的效果,也是我们所担心的。

from esui.

AKIo0O avatar AKIo0O commented on August 25, 2024

事件的target就是目标元素。不需要lib做支持。
事件很明显应该是delegate其控件节点。id做钩子?这样的id明显是guid下的某id。不然会组件间冲突。

复杂的数据,以及DOM和代码。没有考虑到。

代码可以控制所有具体行为。属性可以决定其行为。

from esui.

AKIo0O avatar AKIo0O commented on August 25, 2024

如果代码控制一切。在添加其行为的时候必定改[控制代码]。维护起来是很难的。

如果是属性钩子对应其行为,只需要加一个钩子和对应的行为代码便可。各种行为还可以组合。多个行为的组合对一个钩子来说是不是有点重?

from esui.

otakustay avatar otakustay commented on August 25, 2024

事件的target就是目标元素。不需要lib做支持。

控件的事件与DOM事件不同,控件事件 不得target等属性暴露出去,因此作为控件的使用方,不可能获取到一个DOM元素。控件 必须 处理这一逻辑。

事件很明显应该是delegate其控件节点

控件的目的是什么?如果使用控件的时候还要去操作控件里面的DOM,那么为什么还要做这个控件,而不是提供一堆helper方法让开发人员自己组合着玩呢?

因此,控件对外必须是一个普通的对象,屏蔽一切与DOM结构有关的逻辑。比如一个树,一开始用的<ul>,以后换成<div>,这是控件自己的变更,任何使用这个控件的代码应该不会出错。如果把DOM暴露出去,能保证别人不去依赖元素类型吗?

代码可以控制所有具体行为。属性可以决定其行为。

非常赞同,但这里的代码和属性我更倾向于 均指向一个JS对象 ,通过JS对象的方法控制行为,通过JS对象的属性决定行为。

如果代码控制一切。在添加其行为的时候必定改[控制代码]

  1. 如果DOM控制,是否就不用改控制代码
  2. 添加行为可以通过足够完善的事件机制等给予支持,是否 必定 改控制代码

这么说有点抽象,是否可以举一个实际的例子,能让dom.setAttribute('xxx', xxx);拥有比tree.set('xxx', xxx);好很多的效果?

如果是属性钩子对应其行为,只需要加一个钩子和对应的行为代码便可。各种行为还可以组合。多个行为的组合对一个钩子来说是不是有点重?

不是很理解,是否能有实际应用的示例?

from esui.

AKIo0O avatar AKIo0O commented on August 25, 2024

对于DOM事件以外,target是不需要的。因为钩子已经在DOM事件做了逻辑处理了(分发给对应的控件事件)。

控件是A = Control.extend({type:"A"})。对应的,肯定要暴露出该控件的节点。
new A().nodenew A().el。控件本身必须是Javascript对象。这点是一致的。

这么说有点抽象,是否可以举一个实际的例子,能让dom.setAttribute('xxx', xxx);拥有比tree.set('xxx', xxx);好很多的效果?

这个实际上也是封装了。Control.prototype.set里用this.el.setAttribute。很明显是tree.set要好。

这个例子可能典型的就是form组件。
如果一个form>input元素需要进行多个验证:是否为空是否符合字数限制是否为和谐字符或含有非法字符

一个钩子的情况是input.class='username'或者input#id='username'。你在组件的逻辑里去写对应的3个逻辑。其方法为:

function(){
     //1. 是否为空
    if(isEmpty(v)) ...;
    // 2. 是否符合字数
    if(v.length > 10)....
    ......
    ......
}

而且钩子对应的验证方法很难复用。
如果多个钩子可以 input.data-validates="required range0-10 ...."。便实现了该元素的验证逻辑。

同理如果Tree的节点拥有很多种行为方式,同时在不同的场景需要组合。我们对钩子的处理就会类似于:

   var hooks = {
       hnode: "A B C",  //三种行为
       dnode: "C B"
   };

这样的钩子弱点在于,你无法满足行为组合多样性。而且如果钩子是ID。就有点尴尬了。你要获取所有ID的元素进行逻辑处理。classname的话还好说。

我觉得对于一个控件来说,router尽量是tree.el上delegate来进行分发。所以才有这句:

事件很明显应该是delegate其控件节点

from esui.

otakustay avatar otakustay commented on August 25, 2024

控件上封装set的好处是,可以方便下勾子,看ESUI现在set的实现:

set: function (name, value) {
    var method = this['set' + lib.pascalize(name)];

    if (typeof method == 'function') {
        return method.call(this, value);
    }

    var property = {};
    property[name] = value;
    this.setProperties(property);
}

要加某个属性的勾子,实现一个setXxx就行了,而对应到DOM上的setAttribute直接给使用者的话,这勾子恐怕没这么好下(MutationObserver也没了,怎么监听属性变化呢)

关于验证,可以了解下ESUI的方案,也是高可扩展性的,通过控件上的属性来确定有哪些规则,随后一一调用和HTML5高度一致的API

再说回树这事,可能我们前面的相互理解上有些偏差:

当树触发一个事件时(典型的有expand展开一个节点,collapse收起一个节点),会把这个节点对应的数据(一个纯JS对象,树也是靠这个对象才能生成DOM的)丢给事件监听者。

事件监听者拿到这个对象的一,可以自己处理任何逻辑。这个对象上面,必须有textid属性(用于生成DOM),但不限制其它属性的存在。所以如果要有“勾子”的话,创建树控件的时候,节点上就能加上isAisB之类的属性,虽然不会对应到DOM元素的className上,但起的作用是相同的。这对象上甚至能挂方法,比DOM属性更实用。

最后,几乎所有的控件都是在自己的main元素上绑事件,靠冒泡处理的,这个自然,除非Select这种有一部分不在自己的主元素下面的

from esui.

AKIo0O avatar AKIo0O commented on August 25, 2024

嗯。我先多看看现有的东西。

from esui.

otakustay avatar otakustay commented on August 25, 2024

ef的RemoteTreeStrategy已经实现了,参考:https://github.com/ecomfe/ef/blob/master/src/RemoteTreeStrategy.js

这个问题先到此,有意见再开吧

from esui.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.