【问题标题】:Passing object path as parameter in typescript在打字稿中将对象路径作为参数传递
【发布时间】:2017-11-09 16:24:13
【问题描述】:

我有一种方法可以将数组中的一个对象替换为另一个对象。它将按 ID 搜索并更改所有与指定 ID 匹配的记录。

我想将其更改为通用的、可重用的方法,该方法可以以相同的方式对我传入的任何对象类型进行操作。(例如:car.idcar.door.idcar.trunkMonkey.id 等)

有没有办法让我将“element.car.id”路径作为变量传递给这个方法?

updateArrayObject(item: any, data: any[]) {
        // Parse all objects in the array, looking for matches by ID
        data.forEach(element => {
            if (element.car.id === item.id) { // <-- Can I pass "element.car.id" into the method somehow?
                // Item ID matches. Replace the item.
                element.car = item;
            }
        });
    }

【问题讨论】:

标签: javascript arrays angular typescript


【解决方案1】:

一些程序通过字符串 ("element.car.id") 执行此操作,并在运行时解析路径。不幸的是,它不是类型安全的。

这里有点复杂并且有其局限性,但它是类型安全的:

function updateArrayObject<T, R>( // ElementType, ReplacementType
    data: T[], // The array
    getter: (element: T) => R, // Getter of the thing that might be replaced
    setter: (element: T, replacement: R) => void, // Setter of the replacement, when appropriate
    keyComparer: (candidate: R, replacement: R) => boolean, // The matching predicate
    replacement: R) { // The replacement

    data.forEach(element => {
        if (keyComparer(getter(element), replacement)) {
            setter(element, replacement);
        }
    });
}

var sample: Element[] = [ /* ... */ ];

// Your car example
updateArrayObject<Element, Car>(
    sample,
    e => e.car,
    (e, r) => { e.car = r },
    (left, right) => left.id === right.id,
    {
        id: 42,
        door: { id: 0, name: 'driver' },
        trunkMonkey: { id: 0, tmName: 'bozo' }
    })

// Your trunkMonkey example
updateArrayObject<Element, TrunkMonkey>(
    sample,
    e => e.car.trunkMonkey,
    (e, r) => { e.car.trunkMonkey = r },
    (left, right) => left.id === right.id,
    {
         id: 0, tmName: 'bozo'
    })

// The various custom types involved.
interface Door { id: number, name: string }
interface TrunkMonkey { id : number, tmName: string }
interface Car {
    id: number,
    door: Door,
    trunkMonkey: TrunkMonkey
}
interface Element {
    car: Car,
    otherElementData: any
}

您还可以研究“功能性镜片”。

【讨论】:

  • 你是对的。这比我希望的要复杂,但它似乎可以满足我的所有需求。象鼻猴 Bozo 谢谢你!
【解决方案2】:

这是您的通用函数,cible 可以是 cardoor ...:

updateArrayObject(item: any, data: any[], cible) {
        // Parse all objects in the array, looking for matches by ID
        data.forEach(element => {
            if (element[cible].id === item.id) { // <-- Can I pass "element.car.id" into the method somehow?
                // Item ID matches. Replace the item.
                element[cible]= item;
            }
        });
    }

【讨论】:

  • “你的数组不会被更新,因为元素是他兄弟在数据数组中的克隆”? forEach() 没有克隆并且他没有替换元素,他正在替换元素上成员的值 - 应该没问题。
  • 这看起来像我试图做的,但我很难弄清楚如何调用它。您将什么作为“cible”变量传入?
  • 这类似于传递字符串
  • @Rethic 这样称呼它updateArrayObject(item , data , "car") 抱歉迟到了
猜你喜欢
  • 1970-01-01
  • 2021-06-17
  • 1970-01-01
  • 1970-01-01
  • 2019-10-31
  • 2013-01-25
  • 2020-06-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多