Polymer中JavaScript HTMLElement属性的数据绑定

时间:2016-04-28 12:17:20

标签: javascript data-binding polymer

使用Polymer创建SPA,我需要我的自定义组件都使用代表我的后端API的通用自定义组件,并负责从/向API提供GET-ting / POST-ing数据。它还可用作“缓存”并保存要显示的数据。这样,所有有权访问此单个元素的组件都将共享相同的数据。

所以我想做的就是......:

<my-api>

...但是以编程方式,因为Polymer({ is: 'my-component', properties: { api: { observer: '_onApiChanged', type: HTMLElement }, products: { type: Array }, users: { type: Array } }, _onApiChanged: function(newVal, oldVal) { if (oldVal) oldVal.removeEventListener('users-changed', this._onDataChanged); // Listen for data changes newVal.addEventListener('users-changed', this._onDataChanged); // Forward API object to children this.$.child1.api = newVal; this.$.child2.api = newVal; ... }, _onDataChanged: function() { this.users = this.api.users; // DOESN'T WORK as 'this' === <my-api> this.products = this.api.products; // Plus I'd have to repeat for every array } }); 未在我的所有组件中声明,而是在顶部组件中声明,然后通过JavaScript传递下去:

{  
  "response":{  
    "statusCode":"00",
    "status":"success",
            "responseData":
             [
                   {  
                     "status":1,
                     "themeID":27,
                     "themeName":"ThemeName25",
                     "templateId":22
                    }
             },
                  {  
                     "status":1,
                     "themeID":28,
                     "themeName":"ThemeName28",
                     "templateId":28
                  }
             }
             ]
}

Polymer是否提供了内置方法来实现此目的?我可以通过编程方式创建双花括号绑定吗?

2 个答案:

答案 0 :(得分:0)

我可能会稍微改变一下这种方式:以声明方式传递products / users数组,利用Polymer的绑定系统。或者你可以用这样的方式编写你的my-api元素,它们都共享状态,第一个声明的是主要元素,而未来声明的元素是副本。这可以让你在任何需要的地方声明它们,并通过Polymer的正常方式绑定到值。

但是要回答你的问题,目前还没有办法在不使用私有Polymer API的情况下轻松地以编程方式设置相同类型的绑定。

为了避免重复和绑定问题,您可以使用Polymer的内置listenunlisten方法:

Polymer({
  is: 'my-component',
  properties: {
    api: {
      observer: '_onApiChanged',
      type: HTMLElement
    },
    products: {
       type: Array
    },
    users: {
       type: Array
    }
  },
  _onApiChanged: function(newVal, oldVal) {
    var apiProperties = ['users', 'products'];

    if (oldVal) {
      apiProperties.forEach(function(prop) {
        this.unlisten(oldVal, prop + '-changed', '_onDataChanged');
      });
    }

    // Listen for data changes
    apiProperties.forEach(function(prop) {
      this.listen(newVal, prop + '-changed', '_onDataChanged');
    });

    // Forward API object to children
    this.$.child1.api = newVal;
    this.$.child2.api = newVal;
    ...
  },
  _onDataChanged: function() {
    this.users = this.api.users; // `this` should be the element now
    this.products = this.api.products;
  }
});

鉴于这是一个你正在做的常见模式,你可能会从将Behavior中的一些东西提取到抽象绑定/解除绑定和API元素转发中获得很多好处。

您可以进行的另一项优化工作是查看传递给_onDataChanged的事件,看看您是否可以推断更改了哪个值并更新了相应的属性。这可能会阻止您为每个属性添加一行。

答案 1 :(得分:0)

我最终使用了其他解决方案。而不是手动将顶级<my-api>元素传递给层次结构,而是需要访问此共享数据的任何元素都声明自己的<my-api>

然后在<my-api>元素的声明中,我做了所有实例使用相同的数组引用。因此,每当我更新它们时,它们都会得到更新,而且我不必在HTML层次结构中传递任何内容,这使得事情变得更简单。