2

以具有 details 属性的 Person 类的以下(咖啡脚本)示例为例,该类又具有自己的属性:

class Person
  constructor: ->
    details =
      name: ''
      age: 0

    Object.defineProperty this, 'details',
      enumerable: yes
      get: => details
      set: (value) =>
        console.log 'set details:', value
        details = value

p = new Person

# does NOT trigger details set()
p.details.name = 'Simon'

# DOES trigger details set(), but takes a bit of effort...
details = p.details
details.name = 'Someone else'
p.details = details

显然,如果我只是将姓名和年龄定义为 Person 类的属性,我可以避免这个问题,但这只是一个示例。

是否有任何简单的方法可以让我的详细信息 set() 方法在其属性更改时触发?

4

1 回答 1

2

并不真地。至少不简单。

p与 完全不同的对象p.details。修改p.details根本不会改变任何事情p。所以它不会收到消息。

您需要做的是安装一些代码,使 details 对象在其自身属性发生更改时向其父对象发送消息。这也意味着它需要知道它的父母是什么。

class Person
  constructor: ->
    details =
      name: ''
      age: 0

    Object.defineProperty this, 'details',
      enumerable: yes
      get: -> details
      set: (value) ->
        console.log 'set details:', value
        details = value

        # set parent object to tell when something changes
        value._parent = this

        # create a name setter, which tells it's parent when it changes.
        Object.defineProperty details, 'name',
          enumerable: yes
          get: -> @_name
          set: (value) ->
            @_parent.didUpdateDetails()

     # trigger setter to install hook
     @details = details

   didUpdateDetails: ->
     console.log 'Updated details!'

p = new Person
p.details.name = 'Alex'
# logs: "Updated details!"

是的,这确实有效:http: //jsfiddle.net/PkyaU/1/

但老实说,这有点疯狂。你确定这是你需要做的吗?也许你应该重新考虑你的方法。

于 2013-03-07T02:15:40.013 回答