【问题标题】:gojs nested setDataPropertygojs 嵌套 setDataProperty
【发布时间】:2021-03-12 19:27:53
【问题描述】:

最初我的节点数据看起来像这样:

{
  key: uuid,
  loc: "x y",
  color: color,
  param1: val1,
  param...:val...,
  paramn: valn
}

我决定将我的 gojs 详细信息和节点数据拆分为:

{
  meta: {
    key: uuid,
    loc: "x y",
    color: color
  }.
  data: {
    param1: val1,
    param...:val...,
    paramn: valn
  }
}

但放弃了将密钥移出,因为它看起来需要在根目录下并解决这个问题:

{
  key: uuid,
  meta: {
    loc: "x y",
    color: color
  }.
  data: {
    param1: val1,
    param...:val...,
    paramn: valn
  }
}

我用这样的东西更新了简单的单向绑定:

// old way
new go.Binding('fill', 'color')

// new way
new go.Binding('fill', 'meta', meta => meta.color)

对于双向绑定,我遇到了一些采用 fromLocation 函数的障碍,如下所示:

// This worked fine with a flat state:
// new go.Binding('location', 'loc', go.Point.parse).makeTwoWay(go.Point.stringify),
    
// I decided to move my stat into a sub object called meta with the following:
new go.Binding('location', 'meta', toLocation).makeTwoWay(fromLocation)

我不清楚我需要对位置进行字符串化,所以我不是;但是因为我保存了一些旧图,所以我暂时还在处理它

// This works just fine
const toLocation = (meta, node) => {
  // pulls the loc out of the meta, and parses into go.point
  let output = meta.loc;

  // TODO: Shouldn't need to check for a string since we're storing raw values now
  if (typeof output === 'string') {
    output = go.Point.parse(output);
  }
  console.log('toLocation:', { output, meta });

  return output;
};

我在 fromLocation 中得到了非常奇怪的行为:

const fromLocation = (loc, data, model) => {
  // writes the loc as a string to the meta prop
  console.log('fromLocation IN:', { data: _.cloneDeep(data) });

  const meta = _.cloneDeep(data.meta);
  meta.loc = loc;

  console.log('model.nodeDataArray:', model.nodeDataArray);

  if (typeof data.meta !== 'undefined') {
    console.log('fromLocation has meta:', { meta: data.meta, loc });
  }

  this.diagramReferenceService.startTransaction('updating meta');

  model.setDataProperty(data, 'meta', meta);
  data.meta = meta;

  this.diagramReferenceService.commitTransaction('updating meta');

  console.log('fromLocation OUT:', { data: _.cloneDeep(data) });

};

当我查看 lodash 克隆时填充了元数据,但是关于此步骤的执行方式是将 meta 属性设置为 undefined,但看起来我的任何其他代码都没有修改在这个设定点之后。


我采用了这里的代码: https://gojs.net/extras/bindingSubProperties.html

如下:

    const makeTwoWaySubBinding = (rootkey, targetname, sourcename, conversion, backconversion) => {
      console.log('makeTwoWaySubBinding:', { rootkey, targetname, sourcename, conversion, backconversion })
      const bind = new go.Binding(targetname, rootkey);
      bind.mode = go.Binding.TwoWay;

      bind.converter = (root, target) => {
        const value = root[sourcename];
        if (value === undefined) {
          return target[targetname];
        }
        return (typeof conversion === 'function') ? conversion(value, target) : value;
      };

      bind.backConverter = (value, data, model) => {
        const root = data[rootkey];
        if (model) {
          if (typeof backconversion === 'function') {
            model.setDataProperty(root, sourcename, backconversion(value, root, model));
          } else {
            model.setDataProperty(root, sourcename, value);
          }
        } else {
          root[sourcename] = (typeof backconversion === 'function') ? backconversion(value, root, model) : value;
          return root;
        }
      };

      return bind;
    };

他们的例子是字符串化的,所以我用它并调用如下:

makeTwoWaySubBinding('meta', 'location', 'loc', go.Point.parse, go.Point.stringify)

我也遇到了同样的问题

【问题讨论】:

    标签: gojs


    【解决方案1】:
    const makeLocationTwoWayBind = () => {
    
      const locationTwoWayBind = new go.Binding('location', 'meta');
      locationTwoWayBind.mode = go.Binding.TwoWay;
      locationTwoWayBind.converter = (meta, targetObj) => {
        // gets the location from the node data
        const loc = go.Point.parse(meta.loc);
        return loc;
      };
      locationTwoWayBind.backConverter = (loc, nodeData, model) => {
        // updates the location on the nodeData
        const meta = Object.assign(_.cloneDeep(nodeData.meta), { loc: go.Point.stringify(loc) });
        return meta;
      };
    
      return locationTwoWayBind;
    };
    

    所以问题部分在于我仍在使用loc 另外,我不确定为什么示例代码使用模型方法setDataProperty 似乎转换器执行与简单返回类似的行为


    小吐槽

    The `converter` and `backConverter` were -- IMO -- counterintuitively named.
    The converter takes the data from the model and applies to to the diagram,
    the back converter saves data to the model
    
    that became clear after looking at the input params,
    but gave me pause a number of times
    
    the model function names `toLocation` and `fromLocation`
    don't really help
    I would consider using something like marshall and unmarshall instead.
    
    marshall = backConverter = fromLocation
    unmarshall = converter = toLocatation
    

    无论如何;拥有converter 只需return the parsed location 就足够了,backConverter 需要返回meta,因为metago.Binding 构造函数中指定的键。我处理了在backConverter 中更新metaloc 参数,然后返回更新后的meta

    所以现在我找到了我想要的东西:

    {
      key: uuid,
      meta: {
        loc: "x y", <--- locationTwoWayBind handles this
        color: color
      }.
      data: {
        param1: val1,
        param...:val...,
        paramn: valn
      }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-05-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多