简体   繁体   中英

Data binding in Polymer - function is being removed from bound object

I'm encountering an issue binding an object that contains a function from angular to Polymer 1.0. The function is not being passed through into the target object in the custom element. Here is a simplified code sample:

The custom element has a single property named myprop:

<script>    
    Polymer({
        is: 'my-custom-element',
        properties: {
            myprop: Object
        },
        attached: function () {
            var x = this.myprop.x;       //this is ok
            this.myprop.myfunc();        //myfunc is not defined!   

        }
    });

</script>

Here is the HTML:

<div ng-app="myApp">
    <div ng-controller="myCtrl">
        <my-custom-element myprop="{{myobject}}"></my-custom-element>
    </div>
</div>    

And here is the angular controller:

<script>
    angular.module("myApp", []).controller("myCtrl", function ($scope) {    
        $scope.myobject= {
          x: 4,
          myfunc: function() {
             //function body
          } 
        }    
    });    
</script>

Why isn't the function available in the custom element?

As documented here: https://github.com/Polymer/polymer/blob/3e96425bf0e0ba49b5f1f2fd2b6008e45a206692/PRIMER.md#attribute-deserialization

... objects passed into polymer elements are being passed through JSON.stringify and then JSON.parse (depending on variable type).

Functions will be completely stripped out by JSON.stringify - just checkout out this sample...

console.log( JSON.stringify({x:123,y:function(){ return 123; }}) );
// outputs: {"x":123}

I believe this is the offending line in source...

https://github.com/Polymer/polymer/blob/3b0d10b4da804703d493da7bd0b5c22fc6f7b173/src/micro/attributes.html#L232

... and comments nearby suggest possibility to change this behavior...

Users may override this method on Polymer element prototypes to provide serialization for custom types

You can't call Angular function like you write this.myprop.myfunc(); I can't explain why this is so, but if you want call Angular function from Polymer you can use this.fire('nameEvent') and in Angular controller or run module add event listener like

document.addEventListener('nameEvent', function() {
//function body  
})

I hope that help you. Good luck

I'm not simulating with Angular but I think that {{myobject}} can have a problem. Only with Polymer works fine. Basically I copied your code in the my-element and created my-element-two where I import the it. The result is "My name" printed in the lifecycle attached .

<link rel="import" href="../polymer/polymer.html">

<dom-module id="my-element">
<script>    
    Polymer({
        is: 'my-element',
        properties: {
            myprop: Object,
        },
        attached: function () {
            var x = this.myprop.x;       //this is ok
            this.myprop.myfunc();        //myfunc is not defined!   
        }
    });
</script>
</dom-module>

<dom-module id="my-element-two">
<template>
    <my-element myprop="{{myobject}}"></my-element>
</template>

<script>    
    Polymer({
        is: 'my-element-two',
        properties: {
            myobject: {
                type: Object,
                value: {
                    x: 4,
                    myfunc: function() {
                        console.log("My name");
                    }
                }
            }
        },
    });

</script>
</dom-module>

<!-- results is print "My name" in the console. -->
<my-element-two></my-element-two>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM