Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/flash/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 聚合数据绑定和Immutable.js在一起_Javascript_Data Binding_Polymer_Immutable.js_Custom Element - Fatal编程技术网

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对象的方法,但请注意,它既丑陋又粗糙


    绑定到不可变对象 为了让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'); }
          }
        }
      }
      // ...
    });