时间:2018-12-04 14:56:42

标签: javascript polymer web-component

当我在webcomponents中设置对象y为属性时会出现问题。在我的代码中,它正在监听attributeChangedCallback(attrName, oldVal, newVal)属性的更改,但是当我收到一个新属性时,newVal的值等于[Object object]。为什么会发生?

谢谢

4 个答案:

答案 0 :(得分:0)

由于您未提供任何示例代码,所以我无法弄清楚出了什么问题。

但这是一个支持attributeChangedCallback方法的简单组件。

如果此代码有帮助,那就太好了。但是很高兴看到您的代码以了解失败的原因。

// Class for `<my-el>`
class MyEl extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({mode: 'open'});
  }

  static get observedAttributes() {
    return ['name'];
  }

  attributeChangedCallback(attrName, oldVal, newVal) {
    if (oldVal !== newVal) {
      this.shadowRoot.innerHTML = newVal;
    }
  }
}

// Define our web component
customElements.define('my-el', MyEl);
<my-el name="Frodo Baggins"></my-el>

答案 1 :(得分:0)

HTML元素属性始终为 string 类型。

如果要传递Javascript 对象,则应将其转换为JSON表示法:

<custom-element attribute-name='{ "value": "v1" }'></custom-element>

然后您可以解析它attributeChangedCallback()

var o = JSON.parse( newVal )

答案 2 :(得分:0)

最佳实践建议我们在HTMLElements的attributeChangedCallback方法中处理属性和属性的更改。区分属性是通过html设置的,例如<my-element size=3>;而属性是在js中设置的,例如myElement.size = 3

想法是,我们的HTMLElement子类将具有一个大小设置器,该设置器将设置属性,并允许我们处理attributeChangedCallback中的两种情况,例如

class MyElement extends HTMLElement {
  ...

  get size() {
    return this.getAttribute('size');
  }

  set size(value) {
    this.setAttribute('size', value);
  }

  attributeChangedCallback(name, oldValue, newValue) {
    if (name === 'size') {
      // handle size update here
    }
  }
}

这似乎是一个好主意,因为它允许一个地方处理两种可能的更新大小的方法。实际上,google's HTMLElement best practices guide

鼓励了这一点

话虽如此,鉴于HTML属性只能处理字符串,因此这是有问题的。因此,我们有2种选择

1)忽略最佳实践建议,鉴于HTMLElement仍然是新事物,并且并非最佳实践不一定来自数十年的使用经验,因此这并不是完全不合理的。也许,与将属性更改委派给属性更改完全相反,因为这样做仍然可以实现google的建议目标,即“避免重入问题”并只有一个处理程序。

class MyElement extends HTMLElement {
  ...

  get size() {
    this.size_;
  }

  set size(value) {
    this.size_ = value;
     // handle size update here
  }

  attributeChangedCallback(name, oldValue, newValue) {
    this[name] = newValue;
  }
}

或2)依靠可设置为JS对象的属性的设置器,以及依靠可表示为字符串的属性的attributeChangedCallback。

class MyElement extends HTMLElement {
  ...

  get size() {
    return this.getAttribute('size');
  }

  set size(value) {
    this.setAttribute('size', value);
  }

  get myObj() {
    return this.myObj_;
  }

  set myObj(value) {
    this.myObj_ = value;
    // handle myObj update here
  }

  attributeChangedCallback(name, oldValue, newValue) {
    if (name === 'size') {
      // handle size update here
    }
  }
}

答案 3 :(得分:0)

从文档中:

  

attributeChangedCallback(本机)

     

必须明确注册属性才能观察。

     

对于Polymer元素,仅跟踪在properties对象中显式声明的属性以进行属性更改。 (也就是说,更改属性值会调用属性更改后的回调,并使Polymer从属性中设置属性值。)

     

https://polymer-library.polymer-project.org/2.0/docs/about_20

如果您要获取[对象对象],我猜您需要在properties中声明该对象。


我也不会自己使用attributeChangedCallback,而是在属性上放置一个复杂的观察者。

class XCustom extends Polymer.Element {

  static get is() {return 'x-custom'; }

  static get properties() {
    return {
      user: {
        type: Object,
        value: function() {
          return {};
        }
      }
    }
  }

  // Observe the name sub-property on the user object
  static get observers() {
    return [
        'userNameChanged(user.name)'
    ]
  }

  // For a property or sub-property dependency, the corresponding
  // argument is the new value of the property or sub-property
  userNameChanged(name) {
    if (name) {
      console.log('new name: ' + name);
    } else {
      console.log('user name is undefined');
    }

  }
}

https://polymer-library.polymer-project.org/2.0/docs/devguide/observers#simple-observers