天道酬勤,学无止境

聚合物:如何观察变化特性(Polymer: How to watch for change in <content> properties)

问题

我刚刚开始学习聚合物。 这是我的聚合物元素的通用版本:

<polymer-element name="my-element">
    <template>
        <style>
        :host {
            position:absolute;
            width: 200px;
            height: 100px;
            background-color: green;
        }
        </style>
        <p>my element</p>
        <content id="first-in"></content>
        <content id="second-in"></content>
    </template>
    <script>
    Polymer('my-element', {
        domReady: function() {
            alert(this.children[0].getAttribute('title')); 
            //this returns the value I want to observe
        }
    });
    </script>
<polymer-element>

内容标签都填充了另一个自定义元素(再次稍微简化):

<polymer-element name="in-element" attributes="title">
    <template>
        <style>
        ...
        </style>
        <p>{{title}}</p>
    </template>
    <script>
    Polymer('in-element', {
        title: 'me'
    });
    </script>
<polymer-element>

我希望能够做的是在(任何)元素内(放入内容标签中)中的标题属性发生更改(通过单击事件或其他方式)时调用 my-element 中的函数。 我不确定如何使用observe 访问它,或者我是否需要使用mutationObserver 等。这是如何完成的/是否可能?

回答1

Polymer 的数据绑定系统(例如Object.observe() [info])无法观察到title等原生属性。 避免它们通常是一个好主意。

在您的示例中,我已将title更改为mytitle并使用reflect: true发布它,以便属性值反映回属性。 这样你就可以完全避免.getAttribute()并且只检查.mytitle在元素上。 您还可以在绑定中使用{{mytitle}}

您可以通过突变观察者 [1] 来做到这一点。 Polymer 提供了onMutation来监控孩子,但你想监控孩子的属性。 为此,您需要一个纯 MO:

ready: function() {
  var observer = new MutationObserver(function(mutations) {
    mutations.forEach(function(m) {
      if (m.target.localName == 'in-element') { // only care about in-element
        console.log(m.attributeName, m.oldValue, m.target.mytitle);
      }
    });  
  });
  // Observe attribute changes to child elements
  observer.observe(this, {
    attributes: true,
    subtree: true,
    attributeOldValue: true
  }); 
}

演示:http://jsbin.com/doxafewo/1/edit

domReady() ,我还将您对this.children[0]警报更改为this.$.firstin.getDistributedNodes()[0].mytitle 。 使用getDistributedNodes()更好,因为您可以保证拥有实际通过<content>插入点 [2] 的节点。

回答2

每个属性都有一个观察者。 所以在你的情况下它应该是这样的。 尽管有 2 种不同的实现,一种将属性名称作为函数的第一个参数。

Polymer('in-element', {
    title: 'me',
    titleChanged: function(oldVal, newVal) {
        // do something
    }
});

聚合物变化观察者

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 从DOM中删除并再次插入后如何更新聚合物元素绑定(How to update polymer element bindings after it was removed from DOM and inserted again)
    问题 假设我们有容器聚合物元素和另一个虚拟聚合物元素。 容器聚合物元素具有用于插入另一种聚合物的 div 块。 container_polymer.html <polymer-element name='container-polymer'> <template> <div id="container"> </div> <button on-click="{{first}}">show first</button> <button on-click="{{firstPrepared}}">show first prepared</button> <button on-click="{{second}}">show second</button> </template> <script type="application/dart" src="container_polymer.dart"> </script> </polymer-element> 插入虚拟聚合物有三个按钮: 第一个按钮将第一个虚拟聚合物插入容器。 第二个按钮也插入第一个虚拟聚合物,并在该聚合物上调用prepareElement() 。 第三个按钮将第二个虚拟聚合物插入容器 container_polymer.dart import 'package:polymer/polymer.dart'; import
  • 观察聚合物飞镖的包装(Observe package from polymer dart)
    问题 我试图使用observe包,而不必在模型中具有批注,并且仅通过在设置器中提高notifyPropertyChange,因此要进行测试,我进行了以下测试 import 'package:observe/observe.dart'; import 'dart:async'; import 'dart:math'; void main() { var dummyWatchingModel = new DummyWatchingModel(); new Timer.periodic(new Duration(milliseconds:1000), (_){ //calls a function that set a random value to the property in the observable model dummyWatchingModel.setModelProps(); }); } class Model extends Observable{ int _x; Model(this._x); int get x=> _x; void set x(int value){ _x = notifyPropertyChange(#_x, _x, value); } } class DummyWatchingModel{ Model model = new Model(1)
  • Polymer Dart,全局变量和数据绑定(可观察)(Polymer Dart, global variables and data bindings (observable))
    问题 我阅读了 Polymer API 开发人员指南,但不幸的是,它只有针对 JavaScript 开发人员的示例。 我尝试移植到 Dart 的一些示例,但在这种情况下我失败了。 请访问 https://www.polymer-project.org/0.5/docs/polymer/polymer.html#global(支持全局变量部分)。 这是文档中的剪辑: 元素.html <polymer-element name="app-globals"> <script> (function() { var values = {}; Polymer({ ready: function() { this.values = values; for (var i = 0; i < this.attributes.length; ++i) { var attr = this.attributes[i]; values[attr.nodeName] = attr.value; } } }); })(); </script> </polymer-element> <polymer-element name="my-component"> <template> <app-globals id="globals"></app-globals> <div id="firstname">{{$
  • Polymer元素和AngularJS指令之间有什么区别?(What is the difference between Polymer elements and AngularJS directives?)
    问题 在“聚合物入门”页面上,我们看到了一个正在使用的聚合物示例: <html> <head> <!-- 1. Shim missing platform features --> <script src="polymer-all/platform/platform.js"></script> <!-- 2. Load a component --> <link rel="import" href="x-foo.html"> </head> <body> <!-- 3. Declare the component by its tag. --> <x-foo></x-foo> </body> </html> 您会注意到, <x-foo></x-foo>由platform.js和x-foo.html定义。 似乎这等效于AngularJS中的指令模块: angular.module('xfoo', []) .controller('X-Foo', ['$scope',function($scope) { $scope.text = 'hey hey!'; }) .directive('x-foo', function() { return { restrict: 'EA', replace: true, controller: 'X-Foo', templateUrl: '/views
  • Polymer-AngularJS双向数据绑定(Polymer-AngularJS two-way data binding)
    问题 我有一些使用Polymer创建的自定义元素。 让我们将其称为x输入,它看起来像这样: <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> 我有这个HTML我使用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> 这是JS: var
  • 聚合物Dom重复绑定到内容(Polymer Dom-Repeat Binding to Content)
    问题 在聚合物1.2.3中, dom-repeat是否有可能使用内容作为模板并将值绑定到所提供的元素? 自定义元素: <dom-module id="modify-collection"> <template> <div> <template is="dom-repeat" items="[[collection]]"> <content></content> </template> </div> </template> </dom-module> 用法: <modify-collection collection="{{things}}"> <list-item resource="[[item]]"></list-item> </modify-collection> 我在没有帮助的情况下查看了以下资源: 聚合物:如何观察<content>属性的变化 聚合物1.0模板绑定参考等效项 嵌套聚合物元素之间的数据绑定 https://github.com/grappendorf/grapp-template-ref https://github.com/Trakkasure/dom-bindref https://github.com/Polymer/polymer/issues/1852 https://github.com/Polymer/polymer/pull/2196
  • 如何在聚合物组件内使用Sass(How to use Sass inside a Polymer component)
    问题 我目前正在使用Polymer作为我的前端开发框架。 我爱SASS。 现在我知道我可以像平常一样创建一个Sass文件并将其导入。 但是,我真的养成了在Web组件中使用样式标签的习惯。 基本上,我正在寻找的工作流程是能够简单地在Web组件中定义脚本标签,或者添加type ='sass;。 做到这一点。 然后,在将文件输出到我的.tmp目录之前,仔细研究并编译这些标签中的所有SASS。 用Grunt或Gulp这样的东西可以实现这样的功能吗? 如果是这样,什么是最好的模块可以帮助我实现这一目标? 回答1 我的实现是基于Polymer html文件中标签的替换。 我正在用gulp但可以更改为仅使用fs 。 文件结构应为以下示例: app-view |- app-view.html |- app-view.scss app-view.html: <dom-module id="app-view"> <template> <style> <!-- inject{scss} --> </style> </template> </dom-module> app-view.scss: :host{ margin-top: 50px; justify-content: center; display: flex; } #container{ font-size: 12px; h1{ font
  • 如何将任意数据从Dart聚合物Web组件传递到Click事件处理函数(How do I pass arbitrary data to a click event handler function from a Dart polymer web component)
    问题 在Dart的Web UI中,可以响应事件而传递任意数据以起作用,例如,以下代码段响应按钮的on-click事件,将值2传递给increment(int incBy)方法: <!-- Web UI --> <element name="x-click-counter"> <template> <button on-click="increment(2)"> <!-- passing a value of 2 --> Click me </button> </template> </element> <script> import 'package:web_ui/web_ui.dart'; class CounterComponent extends WebComponent { void increment(int incBy) { // accept the value of 2 count = count + incBy; } } </script> 在Polymer(和Polymer.dart)中,单击事件属性需要函数名称的字符串版本,而不是实际的函数调用。 在聚合物文档页面上对此进行了描述: 事件处理程序属性的值是组件上方法的字符串名称。 与传统语法不同,您不能在属性中放入可执行代码。 使用polymer.dart,它看起来像: <polymer-element
  • 异常:NoSuchMethodError:未找到方法:'whenPolymerReady'(Exception: NoSuchMethodError: method not found: 'whenPolymerReady')
    问题 我正在使用Dart SDK 1.5.3 | 聚合物0.11.0 + 5 | Windows x64。 当我使用模板“使用聚合物库(移动友好)选项的示例Web应用程序”模板创建一个创建的聚合物应用程序并运行该应用程序时,它会按预期工作,并且单击按钮时计数器会增加。 假设页面带有 <script type="application/dart"> export 'package:polymer/init.dart'; </script> 是index.html,尝试通过从index.html中删除以下行来重构应用程序 <click-counter count="5"></click-counter> <link rel="import" href="clickcounter.html"> 导致以下错误: Exception: NoSuchMethodError: method not found: 'whenPolymerReady' Receiver: Instance of 'JsFunction' Arguments: [Closure: () => dynamic] (package:polymer/src/loader.dart:115) Breaking on exception: NoSuchMethodError: method not found:
  • 观察Polymer JS中对象的更改(Observe changes for an object in Polymer JS)
    问题 我有一个要观察的模型对象元素,如下所示: <polymer-element name="note-editor" attributes="noteTitle noteText noteSlug"> <template> <input type="text" value="{{ model.title }}"> <textarea value="{{ model.text }}"></textarea> <note-ajax-button url="/api/notes/" method="POST" model="{{model}}">Create</note-ajax-button> </template> <script> Polymer('note-editor', { attached: function() { this.model = { title: this.noteTitle, text: this.noteText, slug: this.noteSlug } }, }); </script> </polymer-element> 我想观察模型中的更改,但是显然不能在元素中以及在note-ajax-button元素中使用modelChanged回调。 怎么了? 我怎样才能做到这一点? 我尝试过分别观察这些字段,但这根本不干净。
  • 获取聚合物已发布特性的列表(Getting the list of polymer published properties)
    问题 有没有一种方法可以获取聚合物组件中定义的所有已发布特性的列表? (例如,获取组件公共API的可用属性) <polymer-element name="sample-component" attributes="foo1 foo2" bar="10"> /* ... */ </polymer-element> <sample-component foo1="5"></sample-component> document.querySellector('sample-component').attributes; // returns bar and foo1 (which have a value assigned to them) // but I want to get foo1 and foo2 回答1 最好使用element.publish获取element.publish的已发布属性列表。 (在聚合物1.0中, element.properties作用相同)。 element.getAttribute('attributes)将不包括在发布块中设置的发布属性。 回答2 您可以通过element属性访问元素定义(即polymer-element本身)。 所以 document.querySelector('sample-component') .element
  • 在Polymer 1.0中如何对对象而不是数组使用dom-repeat?(How to use dom-repeat with objects instead of arrays in Polymer 1.0?)
    问题 遍历数组myarray=[1, 2, 3]工作原理如下: <template is="dom-repeat" items="[[myarray]]"> <span>[[item]]</span> </template> 如何遍历对象myobject = {a:1, b:2, c:3} ? 回答1 这是一个完整的实现: <test-element obj='{"a": 1, "b": 2, "c": 3}'></test-element> <dom-module id="test-element"> <template> <template is="dom-repeat" items="{{_toArray(obj)}}"> name: <span>{{item.name}}</span> <br> value: <span>{{item.value}}</span> <br> <hr> </template> </template> <script> Polymer({ properties: { obj: Object }, _toArray: function(obj) { return Object.keys(obj).map(function(key) { return { name: key, value: obj[key] }; }); } }); <
  • 如何在Dart组件中合并很棒的字体?(how to incorporate font awesome in a dart component?)
    问题 以下html在文字左侧显示了一个漂亮的相机图标。 尝试对聚合物组件进行样式设置时,如何实现? <!doctype html> <html> <head> <link rel="stylesheet" id="font-awesome-4-css" href="http://astronautweb.co/wp-content/themes/astro2012/css/font-awesome-4.0.3.css?ver=4.0.3" type="text/css" media="all"> </head> <body> <p><i class="fa fa-camera-retro fa-lg"></i> Cool camera</p> </body> 具体来说,应该在哪里包含链接,应将authorstyles设置为什么,模板中的样式应设置为什么。 回答1 编辑 applyAuthorStyles已弃用或已删除。 我还没有尝试过它,但是如果将超棒的字体添加到组件中,它应该可以工作。 这很麻烦,因为需要将样式添加到使用FA的每个组件中。 Pixelate使用带有以下变量的SASS:https://github.com/donny-dont/Pixelate-Flat/blob/master/lib/stylesheets/fonts/_variables
  • 聚合物重复模板“刷新”(polymer repeat template “refresh”)
    问题 需要帮助的概念。 构建一个自定义元素以显示我的数据库中的数据。 使用重复模板,效果很好。 该报告已分组,因此报告中的每一行都包含另一级数据,这些数据将在您深入一行后显示。 因此,现在我希望能够“刷新”报表数据以反映排序或分组更改。 该报告基于指向所显示实际数据的“索引”数组。 我对索引数组中的数据进行排序/分组,然后将此数组用作“模板重复”的数组。 <div id="rptbody"> <template repeat="{{group in groups}}"> <pmg-group groupid={{group.id}} groupval={{group.groupval}} groupobj={{group.groupobj}}></pmg-group> </template> </div> 因此,在此示例中,groups数组是我的数据的键的列表。 在此示例中,groups数组的顺序正确,因此[0]包含数据数组的第一个索引, [length-1]包含最后的索引。 我有一个排序例程,可以更改组中的索引值,但它不会在groups数组中添加或删除项目。 所以我的问题是在我求助之后,如何触发模板以重新扫描组列表? 我发现可以设置groups = [] ,然后从主索引重新加载组( groups.push({idx} ),它会更新模板,但是这对我来说似乎是浪费。
  • 如何在聚合物应用程序中实现主要功能(how to implement a main function in polymer apps)
    问题 我想在使用聚合物的应用程序中实现主要功能。 我试图在实现聚合物代码的dart文件中实现main函数。 该代码未执行。 不允许在主功能中包含第二个飞镖脚本- 我的错误在哪里? Tnx云母。 回答1 index.html <head> <!-- <link rel="import" href="packages/polymer/polymer.html"> not necessary anymore (only in elements)--> <!-- <script src="packages/web_components/platform.js"></script> not necessary anymore with Polymer >= 0.14.0 --> <!-- <script src="packages/web_components/dart_support.js"></script> not necessary anymore with Polymer >= 0.15.0 --> <!-- old --> <script type="application/dart"> export 'package:polymer/init.dart';</script> <!-- new --> <script type="application/dart">export
  • 在Dart中扩展AElement的自定义聚合物元素(Custom Polymer element extending AElement in Dart)
    问题 我想创建自定义的Polymer元素'ab-btn',该元素扩展了'a'元素。 它应该用作: <ab-btn href="http://www.gooogle.com">Google</ab-btn> 我的聚合物元素的html声明看起来像(脚本列在最后,因为我想在一个文件中声明更多元素): <polymer-element name="ab-btn" extends="a"> <template> <content></content> </template> </polymer-element> <script type="application/dart" src="ab-elements.dart"></script> 元素的dart脚本如下: import 'package:polymer/polymer.dart'; import 'dart:svg'; @CustomTag('ab-btn') class AbBtn extends AElement { AbBtn.created() : super.created(); var inputMethodContext; } 当我尝试使用此元素时,我总是会出错: #13 _ZoneDelegate.run (dart:async/zone.dart:417) #14 _CustomizedZone.run (dart
  • 如何观察DOM的变化AngularJS(How to watch the DOM for changes AngularJS)
    问题 这似乎是一个愚蠢的问题,但是我需要知道如何观察页面的整个DOM并在页面发生任何变化时重新对其进行编译。 本质上,这是AngularJS在默认情况下通过使用数据绑定来执行的操作,但是我需要在DOM中的任何内容发生更改时(不仅是绑定)进行更改。 之所以这样,是因为我有一个完全用HTML,Javascript和PHP构建的应用程序。 它是一个单页应用程序,具有一个主页,并将PHP注入该页面中的DIV包装器中。 我想对其进行一些修改,但要使我的代码与原始代码完全分开。 为此,我需要能够在每次注入具有自己的DOM结构的新PHP文件时重新编译DOM。 到目前为止,我似乎没有用。 app.directive("watch", function () { return function (scope, element, attr) { scope.$watch("watch", function(oldValue, newValue) { if(newValue) { console.log("there is a new value"); console.log("the new value is " + newValue); } }); } }); 我在<body>标签中添加了watch属性,但它似乎不起作用,当dom更改时,没有任何记录。 最终,我想用$
  • 如何使用聚合物将HTML注入模板(How to inject HTML into a template with polymer)
    问题 我正在使用polymer-jsonp执行JSONP请求,但响应有时包含html。 例如,假设post.content是"<strong>Foo</strong> bar" ,如何显示{{post.content}}使得"Foo"用粗体显示? <polymer-element name="feed-element" attributes=""> <template> <template repeat="{{post in posts.feed.entry}}"> <p>{{post.content}}</p> </template> <polymer-jsonp url="url" response="{{posts}}"></polymer-jsonp> </template> <script> Polymer('feed-element', { created: function() { }, attached: function() { }, detached: function() { }, attributeChanged: function(attrName, oldVal, newVal) { } }); </script> </polymer-element> 回答1 Polymer不会通过数据绑定标记未转义的HTML,因为它成为XSS攻击的漏洞。
  • 如何测试Polymer Dart(How to test Polymer Dart)
    问题 我开始测试我的Web组件,并注意到Dart有一个很好的库,并且可以与Dart一起很好地工作。 但是现在我也想测试我的Polymer组件,但是我很难做到这一点。 看来我的单元测试无法将我的元素识别为聚合物元素。 我的“测试”现在看起来如何 测试飞镖 import "../../../components/medium/bar-chart.dart"; import "package:unittest/unittest.dart"; import 'package:polymer/polymer.dart'; import 'dart:html'; main() { // initPolymer(); print("--- Bar Chart Test ---"); group('Bar Chart Test', () { test(("queryForBarChart"),() { expect(querySelector('bar-chart'), isNotNull); // PASS }); test(("testtest"),() { // This should pass expect(querySelector('bar-chart').test(), equals(5)); // Test failed: Caught type 'HtmlElement' is
  • 如何观察变量的变化(How to watch a variable for changes)
    问题 我想知道是否有什么办法可以让我在程序运行时观察变量值的变化。 当然不使用调试器,我想以编程方式进行。 例如: class A { public static int valueToBeWatched; } 因此,在运行时,如果在我的项目中任何类的任何方法中修改了此值,则应调用MyValueChangeListner事件。 回答1 您需要用一个类替换int类型,该类将在值更改时调用您的侦听器。 您可能想忽略未实际更改的值的设置。 例如 private int value; private final MyValueChangeListener listener; public void setValue(int value) { if(this.value == value) return; listener.changed(this, this.value, value); this.value = value; } 您可以使用字节码注入执行此替换,但是更改原始代码非常简单。 一种替代方法是监视该值以定期查找更改。 除非值变化非常缓慢,否则您可能看不到每一个变化。 您可以使用Debugger API来执行此操作,但这并不简单,除非您已经熟悉该API,否则我不建议您使用它。 Java调试器API链接 http://java.sun.com/javase/technologies