2

I have some custom element created with Polymer. Let's call it x-input, and it looks like this:

<polymer-element name="x-input" attributes="name">
    <template>
        <input type="text" value={{name}}> <span>{{name}}</span>
        <br />
        <input type="range" value={{age}} > <span>{{age}}</span>
    </template>
 </polymer-element>

And I have this html I use Angular:

<html ng-app="testApp">
    <body ng-controller="AppCtrl">
        <input id="outer_input" type="text" ng-model="kids[0].name" value={{kids[0].name}} /> <br />
        <span>name: {{kids[0].name}} age: {{kids[0].age}}</span><br />
        <x-input ng-repeat="kid in kids" name={{kid.name}} age={{kid.age}}>
        </x-input>
    </body>
</html>

Here is the JS:

var testApp = angular.module('testApp', []);

testApp.controller('AppCtrl', function ($scope, $http)
{
    $scope.kids = [{"name": "Din", "age": 11}, {"name": "Dina", "age": 17}];
}

The problem is with the two-ways data binding. When I change the #outer_input input value the x-input inner values (name and age) are changed.

But when I change the custom element input only inner binded variable are changed.

How can I change value of binded variable within the polymer element and it will change the model and all outer bound UI and data (two-way binding)?

Thanks

vlio20
  • 8,955
  • 18
  • 95
  • 180
  • where is your polymer-element template situated in the html tag? – z.a. May 09 '14 at 12:15
  • Oh I think I see it, you have a typo though, x-inut should be x-input – z.a. May 09 '14 at 12:16
  • Thanks for the correction, but it's not the issue. – vlio20 May 09 '14 at 12:23
  • I think the main problem is that you're not calling `$scope.apply` when the value of `kid.name` or `kid.age` changes. Angular doesn't know that stuff on the scope changes unless you use `apply`. You'll also need to pass the actual `kid` object to the polymer element instead of just the strings it has as attributes so that you can change the properties on the object that angular knows about. – mrmcgreg May 09 '14 at 12:44
  • 1
    @testuser can you show how to pass object to the polymer element? – vlio20 May 09 '14 at 12:47
  • Ugh, that doesn't seem like it will work since the attributes on the `x-input` are strings by the time the polymer element gets a look at them. You might take a look at doing something like the answer here: http://stackoverflow.com/questions/15911300/is-it-possible-to-watch-attributes-changes on the `x-input` element. – mrmcgreg May 09 '14 at 13:18

5 Answers5

6

If you tell it to, Polymer will reflect model changes back out to the published property (its attribute), but issue is that Angular doesn't observer bindings to attributes.

There's a patch that makes this work like you want: https://github.com/eee-c/angular-bind-polymer

More info here: http://blog.sethladd.com/2014/02/angular-and-polymer-data-binding.html

ebidel
  • 23,921
  • 3
  • 63
  • 76
  • It is not possible to bind object. Is it related to the third party libraries? take a look at this SO: http://stackoverflow.com/q/24340258/1691423 – vlio20 Jul 06 '14 at 19:21
2

I started the ng-polymer-elements project which lets you have two-way binding between web components and Angular in an Angular-like way:

<input ng-model="model"/>
<paper-input ng-model="model"></paper-elements>

It comes with support for Polymer core and paper elements, and can be configured for any web component.

Gabriel
  • 862
  • 6
  • 18
1

I belive this is what youre looking for simple and transparent 2 way data binding and capability to expand to more custom elements and for javascript not dart

NG Polymer Elements

Strife86
  • 1,135
  • 1
  • 10
  • 18
  • 1
    Does it supports objects and arrays? – vlio20 Aug 15 '14 at 18:42
  • Im not quite sure what you mean by objects and arrays the library solves some of the common problems (2 way data binding, ng cloak, ng-repeat, etc) of mixing angular and polymer elements, currently support the core-elements and the paper-elements and give the documentation to use add other web elements to the support list – Strife86 Aug 18 '14 at 17:22
  • 1
    according to documentation you can add support for your custom polymer elements with a simple setup – Strife86 Aug 19 '14 at 13:52
  • I've not had success with this. Also, does it support objects and arrays? Currently with the other library angular-bind-polymer i can only get strings to work. – FlavorScape Jan 06 '15 at 23:52
0

This is my working solution, ng-polymer-elements doesn't work for me ($dirty, $pristine, etc. not working). This is very straighforward IMO

angular.module 'tinizen.admin.ui'
.directive 'paperInput', ->
  restrict: 'E'
  require: 'ngModel'
  link: (scope, elem, attrs, ctrl)->

    watcher = ->
      if ctrl.$dirty then ctrl.$invalid else false

    scope.$watch watcher, (invalid)->
      elem[0].invalid = invalid

    updateModel = (inputValue)-> ctrl.$setViewValue inputValue

    ## attrs.$observe 'inputValue', updateModel not working
    ## so I have to use on 'input'
    elem.on 'input', ->
      scope.$apply ->
        updateModel elem.prop('inputValue')

    updateModel()

    ctrl.$render = ->
      elem.prop 'inputValue', ctrl.$viewValue
tungv
  • 107
  • 1
  • 9
0

according to their documentation, when binding to native elements, you have to add an extra binding notation

https://www.polymer-project.org/1.0/docs/devguide/data-binding.html#two-way-native

Here {{name}} will update on input events, the {{age}} only on the change event

<polymer-element name="x-input" attributes="name">
    <template>
        <input type="text" value={{name::input}}> <span>{{name}}</span>
        <br />
        <input type="range" value={{age::change}} > <span>{{age}}</span>
    </template>
 </polymer-element>
Steve
  • 1,995
  • 2
  • 16
  • 25