0

[编辑] 将标题从“JS:用于集合或单个项目的奇异 setter/getter?”

关于编写混合 getter/setter 的能力的一些问题......对于我的国际象棋应用程序,我有一个对象图,它更类似于图而不是树。因此,我决定将各种对象汇集在一个数据结构中,该数据结构同时包含对象实例和 rhem 之间的关系。

就像是 :

// in js/app/base/pools.js
var Pool = function() {
    this.items = {};
    this.relations = {};
};

/**
 * store an object into the pool
 * and augment it with relation/pooling capabilities
 * @param string key
 * @param Object obj
 */
 Pool.prototype.store = function(key, obj) {
    
    var self = this;

    Object.defineProperty(obj.constructor.prototype, "pool", {
        set : undefined,
        get : function() {
            return self;
        }
    });

    this.items[key] = obj;
 };

 /**
  * looks for an object in the pool
  * @param string
  */
 Pool.prototype.find = function(key) {
    return this.items[key];
 };

关系在 Pool 实例的“relations”属性中以对 [obj1, obj2] 的形式存储。我基本上有两种关系:

  • 一对一:像 Chessman <---> Location 这样的一元对应,或者像 Chessman <---> Pawn | 这样的接口实现 ... | 国王

  • 一对多类似 Board [x1] <---> [x64] Tile

    这些关系被设计为(通过池的方式)是双向的,并且必须以原子方式设置(例如事务),因为对象交叉引用需要是“ACID”,对于上面的示例,1 个 Board 包含 64 个 Tiles,每个瓦知道它的常备板。

对于一对一的关系,也许没问题,因为我可以设置:

chessman.location = location;
// AND AT THE SAME TIME :
location.chessman = chessman;

// with two Object.defineProperty(...) combined

问题在于 1-N 关系,因为我可以写:

// 1st : defining relation
// ... (see below)

// 2nd setting a relation
board1.tiles.add(tile_63);
// and
tile_63.board = board1;

// 3rd getting values
board1.tiles --> a collection of tiles (array)
tile_63.board --> board1 object

在主程序中,通过传递参数 object 将关系赋予 Pool 实例:

pool.defineRelation("board-contains-tiles", {
    tiles : { subject : boards.Board, multiple : true },
    board : { subject : tiles.Tile, multiple : false }
});

要定义关系,1-side 是一个普通的 getter/setter,但 N-side 更像是一个 getter-adder,因为我们必须填充(带有瓷砖的板)......所以这不起作用:

 Pool.prototype.defineRelation = function(alias, definition) {
    this.relations[alias] = [];

    var self = this, linker;
    var relation = self.relations[alias];
    var subject, multiple;

    // iterate through relation short names
    for(name in definition) {
        
        subject = definition[name].subject;
        multiple = definition[name].multiple;

        console.log("loop with name : " + name + " subject is : " + subject);

        var getter =  function() {
                var result = [];
                for(r = 0; r < relation.length; r++) {
                    
                    // [x,y] storing
                    if(relation[r][0] == this) 
                        result.push( relation[r][1]);
                    
                    // [y,x] storing
                    if(relation[r][1] == this) 
                        result.push( relation[r][0]);

                    return result;

                };

        var setter;

        if(multiple) {
            setter = function() {};
            setter.add = function(x) { relation.push([this, x]); };
        } else {
            setter = function(x) { relation.push([this, x]); };
        }

        Object.defineProperty(subject.prototype, name, {
            set : setter,
            get : getter
        }); 

    }
};

问题:我认为有可能做到这一点,但如何?或者以更好的方式,比如 Delphi 的 TComponent,或者像 DOM 树?

还请参见:可以在我的网站上找到旧的、丑陋和凌乱的代码库:

www.eozine.fr --> Jet d'echecs --> ColorChess

如果您不想看到以前的结果(2009 年)

问候。

4

1 回答 1

0

可以在“pooler”部分的谷歌代码项目“colorchess”下找到第一个试用版,这是这个动态对象关系池管理器的实际名称。

可以在我的网站 www.eozine.fr/colorchess/javascript(示例 #3)上找到使用 RequireJS 和 Zepto 的示例,但这不是 parmalink!事情必须改善。

也许是早期的 JSfiddle。

2013 年圣诞快乐,2014 年新年快乐。

于 2013-12-22T17:14:59.247 回答