在 Polymer.dart 中无法观察 Safari 8.0(iPad、iOS 8.1.3)中嵌套元素的属性
Cannot observe properties of nested elements in Safari 8.0 (iPad, iOS 8.1.3) in Polymer.dart
我正在尝试观察嵌套 Dart PolymerElements 的 属性 变化。
它适用于 Firefox、Chrome、,但不适用于 iPad (iOS 8.1.3):
上的 Safari 8.0
index.html 文件:
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="mobile-web-app-capable" content="yes">
<link rel="import" href="parent_element.html">
</head>
<body unresolved fullbleed>
<parent-element></parent-element>
<script type="application/dart">export 'package:polymer/init.dart';</script>
<script src="packages/browser/dart.js"></script>
</body>
</html>
parent_element.html 文件:
<link rel="import" href="packages/polymer/polymer.html">
<link rel="import" href="packages/core_elements/core_header_panel.html">
<link rel="import" href="packages/core_elements/core_toolbar.html">
<link rel="import" href="packages/paper_elements/paper_icon_button.html">
<link rel="import" href="packages/paper_elements/paper_button.html">
<link rel="import" href="child-element.html">
<polymer-element name="parent-element">
<template>
<style>
:host, core-header-panel {
height: 100%;
}
</style>
<core-header-panel mode="waterfall" flex>
<core-toolbar class="small">
<div>Observed value in parent is {{logged}}</div>
<span flex></span>
<div id="message"></div>
<child-element id="login-box" logged="{{logged}}"></child-element>
<paper-button on-click="{{doLogin}}" raised hidden?="{{logged}}">Login</paper-button>
<paper-button on-click="{{doLogout}}" raised hidden?="{{!logged}}">Logout</paper-button>
</core-toolbar>
</core-header-panel>
</template>
<script type="application/dart" src="parent-element.dart"></script>
</polymer-element>
父-element.dart文件:
@CustomTag('parent-element')
class ParentElement extends PolymerElement {
ChildElement childElement;
@observable bool logged = false;
ParentElement.created() : super.created() {
//while(children.length > 0) {
// shadowRoot.append(children[0]);
//}
childElement = (shadowRoot.querySelector('#login-box') as ChildElement);
}
void loggedChanged() {
print('loggedChanged: $logged');
}
void doLogin(Event e, var details, Node node) {
childElement.doLogin();
}
void doLogout(Event e, var details, Node node) {
childElement.doLogout();
}
}
子-element.html文件:
<link rel="import" href="packages/polymer/polymer.html">
...
<polymer-element name="child-element">
<template>
<style>
</style>
<paper-action-dialog id="login-dialog" heading="Login to.." transition="core-transition-center" backdrop="" layered="true">
<p>Observed value in child is ({{ logged }})</p>
<paper-button affirmative>Cancel</paper-button>
<paper-button id="login-button" affirmative autofocus >Join</paper-button>
</paper-action-dialog>
</template>
<script type="application/dart" src="child-element.dart"></script>
</polymer-element>
子-element.dart文件:
@CustomTag('child-element')
class ChildElement extends PolymerElement {
bool _loginListen = false;
@published bool logged;
ChildElement.created() : super.created() {
// I can't set onClick listen here because login-button doesn't exists yet. Why?
//var loginBtn = ($['login-button'] as PaperButton); ==> null
//var loginBtn1 = (querySelector('#login-button') as PaperButton); ==> null
}
void doLogin() {
if (!_loginListen) {
PaperButton button = (shadowRoot.querySelector('#login-button') as PaperButton);
button.onClick.listen((Event e) {
_login(e);
});
_loginListen = true;
}
PaperDialogBase dialog = (shadowRoot.querySelector('#login-dialog') as PaperDialogBase);
dialog.toggle();
}
void _login(Event event) {
print('Login...');
logged = true;
}
void doLogout() {
print('Logout...');
logged = false;
}
}
pubspec.yaml 文件:
name: test
version: 0.0.1
description: Test of observers
dependencies:
paper_elements: 0.6.1
polymer: ">=0.15.0 <0.16.0"
browser: 0.10.0
transformers:
- polymer:
entry_points: web/index.html
当我单击按钮 "JOIN"(在子元素中)时,它会触发 "loggedChanged"(在父元素中)并更改文本 "Observed value in parent"(但是不在 iPad) 的 Safari 中。
请告知如何修复它。非常感谢。
p.s。我尝试使用 "dataobject" 而不是 "bool logged":
class DataObject extends Observable {
@observable bool logged = false;
}
但是我得到了同样的效果。
您应该避免访问元素构造函数中的 DOM
childElement = (shadowRoot.querySelector('#login-box') as ChildElement);
此代码应移至生命周期方法之一,如 ready
(与 child-element
中注释掉的代码相同)。
我不知道这是否真的解决了您的问题,但这是您问题中唯一似乎不正确的部分。
我已经创建了错误报告 https://code.google.com/p/dart/issues/detail?id=22275 以及测试样本。
UPD:此效果是由于 paper-action-dialog 中的 paper-button 上存在肯定或不屑一顾的属性。
没有它们,父元素会观察子元素中 属性 的变化。
我已经将 paper-action-dialog 替换为 paper-dialog 并且它可以在 Safari 上运行。
我正在尝试观察嵌套 Dart PolymerElements 的 属性 变化。 它适用于 Firefox、Chrome、,但不适用于 iPad (iOS 8.1.3):
上的 Safari 8.0index.html 文件:
<!DOCTYPE html>
<html>
<head>
<title>Test</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, minimum-scale=1.0, initial-scale=1.0, user-scalable=yes">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="mobile-web-app-capable" content="yes">
<link rel="import" href="parent_element.html">
</head>
<body unresolved fullbleed>
<parent-element></parent-element>
<script type="application/dart">export 'package:polymer/init.dart';</script>
<script src="packages/browser/dart.js"></script>
</body>
</html>
parent_element.html 文件:
<link rel="import" href="packages/polymer/polymer.html">
<link rel="import" href="packages/core_elements/core_header_panel.html">
<link rel="import" href="packages/core_elements/core_toolbar.html">
<link rel="import" href="packages/paper_elements/paper_icon_button.html">
<link rel="import" href="packages/paper_elements/paper_button.html">
<link rel="import" href="child-element.html">
<polymer-element name="parent-element">
<template>
<style>
:host, core-header-panel {
height: 100%;
}
</style>
<core-header-panel mode="waterfall" flex>
<core-toolbar class="small">
<div>Observed value in parent is {{logged}}</div>
<span flex></span>
<div id="message"></div>
<child-element id="login-box" logged="{{logged}}"></child-element>
<paper-button on-click="{{doLogin}}" raised hidden?="{{logged}}">Login</paper-button>
<paper-button on-click="{{doLogout}}" raised hidden?="{{!logged}}">Logout</paper-button>
</core-toolbar>
</core-header-panel>
</template>
<script type="application/dart" src="parent-element.dart"></script>
</polymer-element>
父-element.dart文件:
@CustomTag('parent-element')
class ParentElement extends PolymerElement {
ChildElement childElement;
@observable bool logged = false;
ParentElement.created() : super.created() {
//while(children.length > 0) {
// shadowRoot.append(children[0]);
//}
childElement = (shadowRoot.querySelector('#login-box') as ChildElement);
}
void loggedChanged() {
print('loggedChanged: $logged');
}
void doLogin(Event e, var details, Node node) {
childElement.doLogin();
}
void doLogout(Event e, var details, Node node) {
childElement.doLogout();
}
}
子-element.html文件:
<link rel="import" href="packages/polymer/polymer.html">
...
<polymer-element name="child-element">
<template>
<style>
</style>
<paper-action-dialog id="login-dialog" heading="Login to.." transition="core-transition-center" backdrop="" layered="true">
<p>Observed value in child is ({{ logged }})</p>
<paper-button affirmative>Cancel</paper-button>
<paper-button id="login-button" affirmative autofocus >Join</paper-button>
</paper-action-dialog>
</template>
<script type="application/dart" src="child-element.dart"></script>
</polymer-element>
子-element.dart文件:
@CustomTag('child-element')
class ChildElement extends PolymerElement {
bool _loginListen = false;
@published bool logged;
ChildElement.created() : super.created() {
// I can't set onClick listen here because login-button doesn't exists yet. Why?
//var loginBtn = ($['login-button'] as PaperButton); ==> null
//var loginBtn1 = (querySelector('#login-button') as PaperButton); ==> null
}
void doLogin() {
if (!_loginListen) {
PaperButton button = (shadowRoot.querySelector('#login-button') as PaperButton);
button.onClick.listen((Event e) {
_login(e);
});
_loginListen = true;
}
PaperDialogBase dialog = (shadowRoot.querySelector('#login-dialog') as PaperDialogBase);
dialog.toggle();
}
void _login(Event event) {
print('Login...');
logged = true;
}
void doLogout() {
print('Logout...');
logged = false;
}
}
pubspec.yaml 文件:
name: test
version: 0.0.1
description: Test of observers
dependencies:
paper_elements: 0.6.1
polymer: ">=0.15.0 <0.16.0"
browser: 0.10.0
transformers:
- polymer:
entry_points: web/index.html
当我单击按钮 "JOIN"(在子元素中)时,它会触发 "loggedChanged"(在父元素中)并更改文本 "Observed value in parent"(但是不在 iPad) 的 Safari 中。
请告知如何修复它。非常感谢。
p.s。我尝试使用 "dataobject" 而不是 "bool logged":
class DataObject extends Observable {
@observable bool logged = false;
}
但是我得到了同样的效果。
您应该避免访问元素构造函数中的 DOM
childElement = (shadowRoot.querySelector('#login-box') as ChildElement);
此代码应移至生命周期方法之一,如 ready
(与 child-element
中注释掉的代码相同)。
我不知道这是否真的解决了您的问题,但这是您问题中唯一似乎不正确的部分。
我已经创建了错误报告 https://code.google.com/p/dart/issues/detail?id=22275 以及测试样本。
UPD:此效果是由于 paper-action-dialog 中的 paper-button 上存在肯定或不屑一顾的属性。 没有它们,父元素会观察子元素中 属性 的变化。 我已经将 paper-action-dialog 替换为 paper-dialog 并且它可以在 Safari 上运行。