Привязка данных в Polymer - функция удаляется из привязанного объекта

Я столкнулся с проблемой привязки объекта, содержащего функцию из angular, к Polymer 1.0. Функция не передается в целевой объект в пользовательском элементе. Вот упрощенный пример кода:

Пользовательский элемент имеет одно свойство с именем 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>

Вот HTML:

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

А вот и угловой контроллер:

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

Почему функция недоступна в пользовательском элементе?


person Steven Smith    schedule 07.07.2015    source источник
comment
Если {{myobject}} возвращает объект, это должно работать.   -  person horacioibrahim    schedule 07.07.2015


Ответы (3)


Как описано здесь: https://github.com/Polymer/polymer/blob/3e96425bf0e0ba49b5f1f2fd2b6008e45a206692/PRIMER.md#attribute-deserialization

... объекты, переданные в полимерные элементы, проходят через JSON.stringify, а затем JSON.parse (в зависимости от типа переменной).

Функции будут полностью удалены с помощью JSON.stringify — просто ознакомьтесь с этим образцом...

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

Я считаю, что это оскорбительная строка в источнике...

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

... и комментарии рядом предлагают возможность изменить это поведение...

Пользователи могут переопределить этот метод для прототипов элементов Polymer, чтобы обеспечить сериализацию для пользовательских типов.

person Billy Moon    schedule 07.07.2015
comment
Спасибо за помощь. Я отмечаю это как ответ. Хотя я немного сбит с толку, почему пример кода от horacioibrahim предполагает, что функция сохраняется, когда angular выводится из уравнения. - person Steven Smith; 07.07.2015
comment
@StevenSmith Я думаю, что образец horacioibrahim работает, потому что он не передается извне через атрибут, а скорее напрямую привязывается к внутреннему свойству, которое может быть установлено на все, что может обрабатывать javascript. - person Billy Moon; 08.07.2015

Вы не можете вызывать функцию Angular, как вы пишете this.myprop.myfunc(); Я не могу объяснить, почему это так, но если вы хотите вызвать функцию Angular из Polymer, вы можете использовать this.fire('nameEvent') и в контроллере Angular или запустить модуль, добавив прослушиватель событий, например

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

Надеюсь, это поможет вам. Удачи

person Maksym Galich    schedule 07.07.2015
comment
Спасибо за помощь. - person Steven Smith; 07.07.2015

Я не моделирую с помощью Angular, но думаю, что у {{myobject}} могут быть проблемы. Только с Polymer работает нормально. По сути, я скопировал ваш код в my-element и создал my-element-two, куда я его импортирую. Результатом является «Мое имя», напечатанное в жизненном цикле 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>
person horacioibrahim    schedule 07.07.2015
comment
Спасибо за вашу помощь и за время, потраченное на создание этого образца. - person Steven Smith; 07.07.2015