Javascript 聚合数据绑定和Immutable.js在一起
考虑以下自定义聚合物元素的用法Javascript 聚合数据绑定和Immutable.js在一起,javascript,data-binding,polymer,immutable.js,custom-element,Javascript,Data Binding,Polymer,Immutable.js,Custom Element,考虑以下自定义聚合物元素的用法 <app-header bar-foo="[[abc.def.ghi]]" app-title="[[appTitle]]"></app-header> 但是,这仅更新appTitle而不是abc.def.ghi。为了同时更新此值,您需要按照以下步骤进行操作: this.abc = {def: {ghi: 10}}; 如果有人知道这是为什么,请让我知道 无论如何,因为这个,我想用! 但是,这会带来一些关于如何将数据绑定到自定义元素的问题
<app-header bar-foo="[[abc.def.ghi]]" app-title="[[appTitle]]"></app-header>
但是,这仅更新appTitle
而不是abc.def.ghi
。为了同时更新此值,您需要按照以下步骤进行操作:
this.abc = {def: {ghi: 10}};
如果有人知道这是为什么,请让我知道
无论如何,因为这个,我想用!
但是,这会带来一些关于如何将数据绑定到自定义元素的问题
下面是一个示例片段:
<dom-module id="my-app">
<template>
<app-header hits="[[state.get('page').get('hits')]]"></app-header>
</template>
<script>
(function () {
class MyApp {
beforeRegister() {
this.is = 'my-app';
this.properties = {
state: {
type: Object,
notify: true,
value: Immutable.Map({
page: Immutable.Map({hits: 10})
})
}
};
}
}
Polymer(MyApp);
})();
</script>
</dom-module>
(功能(){
类MyApp{
注册前{
this.is=‘我的应用程序’;
此属性={
声明:{
类型:对象,
通知:正确,
值:Immutable.Map({
页面:Immutable.Map({hits:10})
})
}
};
}
}
聚合物(MyApp);
})();
因此,将数据绑定到元素时会出现问题:
<app-header hits="[[state.get('page').get('hits')]]"></app-header>
这样的事情是可能的还是我做的其他事情完全错了?当你更新结构数据时,你应该使用Polymer API。这将触发已更改的事件,绑定的数据将更新。查看路径更改通知。在这种情况下,您需要将代码更改为:
this.set('abc.def.ghi', 10);
我不熟悉Immutable,但是,这种表达在聚合物中不受支持
hits="[[state.get('page').get('hits')]]"
您可以绑定到元素或计算函数的(子)属性。计算函数必须在元素中定义。不能对数据绑定中的任意对象调用任意函数。
也许,使用
set
API将消除使用Immutable的需要。我知道这篇文章有点老了,但我想回答,因为我想探索同时使用Immutable JS和polymer,因为:
绑定到不可变对象 为了让polymer访问不可变的js属性,您需要在元素原型上创建一个类型为
Object
的属性,作为不可变js和polymer之间的一种“适配器”
此对象属性必须使用javascript(或object.defineProperty
),以便聚合API可以object.property
的形式访问对象,但实际实现将访问不可变对象
let immutableMap = Immutable.map({count: 0, text: 'world'});
Polymer({
// ...
properties: {
/**
* This property is an 'adapter' to assign a property path to access the immutablejs object.
* The property starts with an underscore because we don't want the user to set it
*/
_adapter: {
type: Object,
value: {
/**
* the properties of this object use
* [getters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get)
* so that polyer can access the object like `obj.count`
*/
get count() { return immutableMap.get('count'); },
get text() { return immutableMap.get('text'); }
}
}
}
// ...
});
因此,在上面的示例中,我创建了一个类型为Object
的属性,它有两种方法:count
和text
。因为这些方法前面有get
,所以应该只通过方法名访问它们——这是一个
这样做可以使polymer绑定到\u适配器
对象,然后该对象从immutableMap
中“获取”值
更改不可变对象
完成这项工作所需的第二件事是更改不可变对象。因为对象是不可变的,所以双向绑定不是一个选项。使用immutable时,必须添加事件监听器,这些监听器将重新分配immutable对象并重新渲染
要做到这一点,你必须这样做。我尝试过使用notifyPath
,但我发现这并不例外。应该有用
警告
由于我们覆盖脏检查,并且没有使用虚拟dom库(如react),因此使用不可变对象需要在每次不可变对象中发生更改时重新呈现使用\u适配器的任何元素。但这可以通过使用来改进
完整演示(带撤消)
下面是不可变js和聚合物的完整演示。我添加了一个撤销特性,以鼓励使用immutable——immutable JS使撤销和重做变得非常简单:D
单击[[u adapter.count]]
您好,[[u adapter.text]]!
撤消
//不可变映射的定义超出了聚合对象的范围
设immutableMap=Immutable.Map({
计数:0,
文字:“世界”
});
//添加撤消
设undos=[];
聚合物({
是‘你好,世界’,
/**
*每个事件都应重新分配“immutableMap”,然后手动分配“notifyPath”`
*/
onButtonClick:函数(){
撤销推送(不可变映射);
immutableMap=immutableMap.update('count',count=>count+1);
这个.notifyPath(“_adapter.count”);
},
onInput:函数(事件){
撤销推送(不可变映射);
immutableMap=immutableMap.set('text',event.target.value);
这个.notifyPath(“u adapter.text”);
},
onUndo:函数(){
如果(撤消长度){
immutableMap=undos.pop();
}
const obj=此适配器;
这个。_适配器={};
此。_适配器=obj;
},
特性:{
/**
*此属性是一个“适配器”,用于分配访问immutablejs对象的属性路径。
*属性以下划线开头,因为我们不希望用户设置它
*/
_适配器:{
类型:对象,
价值:{
/**
*此对象的属性使用
*[获取者](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get)
*这样聚合物就可以接触到像“obj.count”这样的物体`
*/
get count(){return immutableMap.get('count');},
get text(){return immutableMap.get('text');}
}
}
}
});
let immutableMap = Immutable.map({count: 0, text: 'world'});
Polymer({
// ...
properties: {
/**
* This property is an 'adapter' to assign a property path to access the immutablejs object.
* The property starts with an underscore because we don't want the user to set it
*/
_adapter: {
type: Object,
value: {
/**
* the properties of this object use
* [getters](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Functions/get)
* so that polyer can access the object like `obj.count`
*/
get count() { return immutableMap.get('count'); },
get text() { return immutableMap.get('text'); }
}
}
}
// ...
});