Javascript 聚合物1.0全局变量

Javascript 聚合物1.0全局变量,javascript,html,polymer,polymer-1.0,Javascript,Html,Polymer,Polymer 1.0,在Polymer 0.5中,关于globals的建议如下所述: 然而,在聚合物1.0中,这似乎不起作用。更改通知不会在基础模型上自动生成,而是在上生成,这意味着更改通知将仅在中的一个上生成 在Polymer 1.0中实现此模式的推荐方法是什么?我已经实现了类似于iron signals用于此目的的模式。因此,基本原则是在发生更新时手动通知其他实例 考虑这一点: <dom-module id="x-global"> <script> (function() { var

在Polymer 0.5中,关于globals的建议如下所述:

然而,在聚合物1.0中,这似乎不起作用。更改通知不会在基础模型上自动生成,而是在
上生成,这意味着更改通知将仅在
中的一个上生成


在Polymer 1.0中实现此模式的推荐方法是什么?

我已经实现了类似于
iron signals
用于此目的的模式。因此,基本原则是在发生更新时手动通知其他实例

考虑这一点:

<dom-module id="x-global">
<script>
(function() {
  var instances = [];

  var dataGlobal = {};

  Polymer({
    is: 'x-global',

    properties: {
      data: {
        type: Object,
        value: dataGlobal,
      },
    },

    attached: function() {
      instances.push(this);
    },

    detached: function() {
      var i = instances.indexOf(this);
      if (i >= 0) {
        instances.splice(i, 1);
      }
    },

    set_: function(path, value) {
      this.set(path, value);

      instances.forEach(function(instance) {
        if (instance !== this) { // if it is not this one
          instance.notifyPath(path, value);
        }
      }.bind(this));
    },

    notifyPath_: function(path, value) {
      instances.forEach(function(instance) {
        instance.notifyPath(path, value);
      });
    },

    fire_: function(name, d) {
      instances.forEach(function(instance) {
        instance.fire(name, d);
      });
    },
  });
})();
</script>
</dom-module>

(功能(){
var实例=[];
var dataGlobal={};
聚合物({
是:“x-global”,
特性:{
数据:{
类型:对象,
值:dataGlobal,
},
},
附:函数(){
实例。推(这个);
},
分离:函数(){
var i=instances.indexOf(this);
如果(i>=0){
实例.拼接(i,1);
}
},
设置:函数(路径、值){
设置(路径、值);
forEach(函数(实例){
如果(实例!==this){//如果不是这个
notifyPath(路径,值);
}
}.约束(这个);
},
notifyPath:函数(路径,值){
forEach(函数(实例){
notifyPath(路径,值);
});
},
消防:功能(名称,d){
forEach(函数(实例){
例如:火灾(名称,d);
});
},
});
})();
在触发事件时,您只需调用带有下划线后缀的版本,如
fire\uu
。我想,你甚至可以用这种模式创造某种聚合物的行为

请注意,前面的下划线属性已由Polymer使用,因此不要继续将其转换为
\u fire

附言:
我没有环顾四周去解决如何反映this.push(数组,值)的通知因为我不需要它。我不知道这样是否可行。应该去找Polymer.Base.push

Sjmiles,Polymer的一位创建者刚刚将以下内容作为共享数据的示例发布到:

<!doctype html>
<html>
<head>

  <meta charset="utf-8">

  <meta name="description" content="shared-data element and repeats">

  <base href="http://milestech.net/components/">

  <script href="webcomponentsjs/webcomponents-lite.min.js"></script>
  <link href="polymer/polymer.html" rel="import">

</head>
<body>

  <demo-test></demo-test>

  <script>

    (function() {
      var private_data = [{name: 'a'}, {name: 'b'}, {name: 'c'}];
      Polymer({
        is: 'private-shared-data',
        properties: {
          data: {
            type: Object,
            notify: true,
            value: function() {
              return private_data;
            }
          }
        }
      });
    })();

    Polymer({
      is: 'xh-api-device',
      properties: {
        data: {
          type: Array,
          notify: true
        },
        _share: {
          value: document.createElement('private-shared-data')
        }
      },
      observers: [
        'dataChanged(data.*)'
      ],
      ready: function() {
        this.data = this._share.data;
        this.listen(this._share, 'data-changed', 'sharedDataChanged');
      },
      dataChanged: function(info) {
        this._share.fire('data-changed', info, {bubbles: false});
      },
      sharedDataChanged: function(e) {
        this.fire(e.type, e.detail);
      },
      add: function(name) {
        this.push('data', {name: name});
      }
    });

  </script>

  <dom-module id="demo-test">
    <template>

      <h2>One</h2>

      <xh-api-device id="devices" data="{{data}}"></xh-api-device>

      <template is="dom-repeat" items="{{data}}">
        <div>name: <span>{{item.name}}</span></div>
      </template>

      <h2>Two</h2>

      <xh-api-device data="{{data2}}"></xh-api-device>

      <template is="dom-repeat" items="{{data2}}">
        <div>name: <span>{{item.name}}</span></div>
      </template>

      <br>
      <br>

      <button on-click="populate">Populate</button>

    </template>
    <script>
      Polymer({
        populate: function() {
          this.$.devices.add((Math.random()*100).toFixed(2));
          // this works too
          //this.push('data', {name: (Math.random()*100).toFixed(2)});
        }
      });
    </script>
  </dom-module>

</body>
</html>

(功能(){
var private_data=[{name:'a'},{name:'b'},{name:'c'}];
聚合物({
is:'专用共享数据',
特性:{
数据:{
类型:对象,
通知:正确,
值:函数(){
返回私有数据;
}
}
}
});
})();
聚合物({
是:“xh api设备”,
特性:{
数据:{
类型:数组,
通知:正确
},
_分享:{
值:document.createElement('private-shared-data')
}
},
观察员:[
'数据更改(数据。*)'
],
就绪:函数(){
this.data=this.\u share.data;
this.listen(this._share,'data changed','sharedDataChanged');
},
数据更改:功能(信息){
这个._share.fire('data-changed',info,{bubbles:false});
},
sharedDataChanged:函数(e){
该火灾(e.类型,e.细节);
},
添加:函数(名称){
this.push('data',{name:name});
}
});
一个
名称:{{item.name}
两个
名称:{{item.name}


居住于 聚合物({ 填充:函数(){ 这个.$.devices.add((Math.random()*100).toFixed(2)); //这也行 //this.push('data',{name:(Math.random()*100).toFixed(2)}); } });

实际上,我已经将我的应用程序改为使用简单的数据绑定,所以我不确定这种方法的有效性,但可能对某些人有用。

我已经将以太酮的解决方案扩展为行为,并扩展了“set”和“notifyPath”方法以自动触发更新。这是我所能实现的跨组件/元素的真正数据绑定:

globals behavior.html:

<script>
var instances = [];
var dataGlobal = {};

var GlobalsBehaviour = {

  properties: {
    globals: {
      type: Object,
      notify: true,
      value: dataGlobal
    }
  },

  ready: function() {
    var _setOrig = this.set;
    var _notifyPathOrig = this.notifyPath;
    this.set = function() {
      _setOrig.apply(this, arguments);
      if (arguments[0].split(".")[0] === "globals") {
        this.invokeInstances(_notifyPathOrig, arguments);
      }
    };
    this.notifyPath = function(path, value) {
      _notifyPathOrig.apply(this, arguments);
      if (arguments[0].split(".")[0] === "globals") {
        this.invokeInstances(_notifyPathOrig, arguments);
      }
    };
  },

  invokeInstances: function(fn, args) {
    var i;
    for (i = 0; i < instances.length; i++) {
      instance = instances[i];
      if (instance !== this) {
        fn.apply(instance, args);
      }
    }
  },

  attached: function() {
    instances.push(this);
  },

  detached: function() {
    var i;
    i = instances.indexOf(this);
    if (i >= 0) {
      instances.splice(i, 1);
    }
  }
};

</script>
<dom-module id="app-data"></dom-module>
<script>
(function () {
    var instances = [];
    var vars = Object.create(Polymer.Base);

    Polymer({
        is: 'app-data',
        properties: {
           data: {
                type: Object,
                value: '',
                notify: true,
                readonly: false,
                observer: '_data_changed'
            },
          key: String
        },
        created: function () {
          key = this.getAttribute('key');
          if (!key){
            console.log(this);
            throw('app-data element requires key');
          }

          instances.push({key:key, instance:this});
        },

        detached: function () {
            key = this.getAttribute('key');
            var i = instances.indexOf({key:key, instance:this});
            if (i >= 0) {
                instances.splice(i, 1);
            }
        },

      _data_changed: function (newvalue, oldvalue) {
        key = this.getAttribute('key');
        if (!key){
            throw('_data_changed: app-data element requires key');
            }
        vars.set(key, newvalue);

        // notify the instances with the correct key
        for (var i = 0; i < instances.length; i++) 
        {
          if(instances[i].key == key)
          {
            instances[i].instance.notifyPath('data', newvalue);
          }
        }
      }


    });
})();
</script>

var实例=[];
var dataGlobal={};
变量globalsbehavior={
特性:{
全球:{
类型:对象,
通知:正确,
值:dataGlobal
}
},
就绪:函数(){
var_setOrig=this.set;
var\u notifypathrig=this.notifyPath;
this.set=函数(){
_setOrig.apply(这个,参数);
if(参数[0]。拆分(“.”[0]=“全局”){
this.invokeInstances(_notifypathrig,arguments);
}
};
this.notifyPath=函数(路径,值){
_notifypathrig.apply(这个,参数);
if(参数[0]。拆分(“.”[0]=“全局”){
this.invokeInstances(_notifypathrig,arguments);
}
};
},
调用实例:函数(fn,args){
var i;
对于(i=0;i=0){
实例.拼接(i,1);
}
}
};
在所有聚合物元素中,应能够访问全局变量:

  <script>
    Polymer({
      is: 'globals-enabled-element',
      behaviors: [GlobalsBehaviour]
    });
  </script>

聚合物({
是:'全局启用元素',
行为:[全球行为]
});
示例:
  • 我已经发布了一个完整的例子作为例子
  • 这里有一个片段可以看到它的作用:
  • 
    全局行为示例
    var实例=[];
    var dataGlobal={};
    变量globalsbehavior={
    特性:{
    全球:{
    类型:对象,
    通知:tru
    
    <dom-module id="app-navigation">
        <style>
    
        </style>
        <template>
            <app-data id="data01" data="{{data1}}" ></app-data>
            <app-data id="data02" data="{{data2}}"></app-data>
            <span>{{data1.loader}}</span>
            <span>{{data2.loader}}</span>
        </template>
    
    </dom-module>
    <script>
    
        (function () {
            Polymer({
                is: 'app-navigation',
                properties: {
                },
                ready: function () {
                    this.data1.loader=51;
                }
            });
        })();
    </script>
    
    <app-data  key="fName" data="{{firstName}}" ></app-data>
    
    <!-- Output element -->
    <dom-module id="output-element" >
      <template>
        <app-data key="fName" data="{{data1}}" ></app-data>
        <app-data key="lName" data="{{data2}}" ></app-data>
        <h4>Output-Element</h4>
        <div>First Name: <span>{{data1}}</span></div>
        <div>Last Name: <span>{{data2}}</span></div>
      </template>
    </dom-module>
    
    <script>Polymer({is:'output-element'});</script>
    
    <dom-module id="app-data"></dom-module>
    <script>
    (function () {
        var instances = [];
        var vars = Object.create(Polymer.Base);
    
        Polymer({
            is: 'app-data',
            properties: {
               data: {
                    type: Object,
                    value: '',
                    notify: true,
                    readonly: false,
                    observer: '_data_changed'
                },
              key: String
            },
            created: function () {
              key = this.getAttribute('key');
              if (!key){
                console.log(this);
                throw('app-data element requires key');
              }
    
              instances.push({key:key, instance:this});
            },
    
            detached: function () {
                key = this.getAttribute('key');
                var i = instances.indexOf({key:key, instance:this});
                if (i >= 0) {
                    instances.splice(i, 1);
                }
            },
    
          _data_changed: function (newvalue, oldvalue) {
            key = this.getAttribute('key');
            if (!key){
                throw('_data_changed: app-data element requires key');
                }
            vars.set(key, newvalue);
    
            // notify the instances with the correct key
            for (var i = 0; i < instances.length; i++) 
            {
              if(instances[i].key == key)
              {
                instances[i].instance.notifyPath('data', newvalue);
              }
            }
          }
    
    
        });
    })();
    </script>
    
    ready: function() {
      const key = this.getAttribute('key')
      if (!key) {
        throw new Error('cm-app-global element requires key')
      }
    
      const val = vars.get(key)
      if (!!val) {
        this.set('data', val)
      }
    },