AJAX 加载聚合物元素和 运行 它的方法
AJAX Load Polymer Element and run it's methods
这是我的情况:我有一个应用程序 shell 和控制器 类 来加载其中包含自定义聚合物元素的模板。到目前为止,我加载了模板并添加到 DOM 中,乍一看一切正常。
将模板内容添加到 DOM 后,我尝试访问自定义元素方法,但我无法访问它。如果我尝试调试代码和 运行 控制台中的重要步骤,那么我可以访问元素方法。
我的元素:
<link rel="import" href="../../components/polymer/polymer.html" />
<dom-module is="app-login">
<template>
<style>
:host { display: block; }
:host.hide { display: none; }
</style>
<div> samle content </div>
</template>
<script>
Polymer({
is: 'app-login',
run: function() {
return new Promise(function(resolve, reject) {
resolve({'id':0,'name':'user'});
});
},
close: function() {
this.classList.add('hide');
}
});
</script>
</dom-module>
我的程序:
// [...]
// this works fine, I just add for better understanding
getTemplate( templateName ) {
return new Promise(function(resolve, reject)
{
fetch( 'templates/'+templateName+'.html' ).then(response => {
document.getElementById('templates').innerHTML += response.text();
resolve(response);
}).catch(error => { reject(error); });
});
};
// [...]
// this method called by the main program and cant't access to the element methods
doLogin() {
this.getTemplate('login').then(templateResponse => {
let Login = document.querySelector('app-login'); // <app-login>...</app-login>
Login.run(); // TypeError: Login.run is not a function
});
};
// [...]
templates/login.html:
<link rel="import" href="elements/app-login/app-login.html" />
<app-login></app-login>
控制台调试:
let Login = document.querySelector('app-login');
//Return: <app-login>...</app-login>
Login.run();
//Return: Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
我试过搜索这个但是我找不到任何相关的答案,以前有人用某种方式解决过这个问题吗?
已经尝试过:
- 将元素添加到 DOM 后设置超时 » 同样的结果
- 将 _ 添加到方法名称(如纸元素方法)» 相同的结果
- 将元素插入 DOM 后等待 WebComponentsReady 事件 » 事件未触发,程序停止
深入研究主题并在 google 上的 polymer-dev 组寻求帮助; Karl Tiedt (@ktiedt) 解决了我的问题:
解决方案是使用 Polymer importHref 和 dom().appendChild 而不是简单的 responseText 追加到容器元素。这些方法不可用,因为元素解析不同,据我所知,如果将 HTML 文本附加到容器的内部 HTML,则 javascript 无法访问元素 shadowDOM。
我更改了 getTemplate 方法以使用 Polymer importHref 并使用 Polymer.dom().appendChild.
附加容器
关于 importHref 用法的信息:
https://www.polymer-project.org/1.0/docs/devguide/instance-methods#imports-and-urls
getTemplate( templateName )
{
let templateFile = this.baseURL+'templates/'+templateName+'.html';
return new Promise(function(resolve, reject)
{
let templateRequest = Polymer.Base.importHref(templateFile,
function()
{
Polymer.dom(document.getElementById('templates'))
.appendChild(templateRequest.import.body);
resolve(templateRequest);
},
function(error)
{
reject(error);
});
});
};
这是我的情况:我有一个应用程序 shell 和控制器 类 来加载其中包含自定义聚合物元素的模板。到目前为止,我加载了模板并添加到 DOM 中,乍一看一切正常。
将模板内容添加到 DOM 后,我尝试访问自定义元素方法,但我无法访问它。如果我尝试调试代码和 运行 控制台中的重要步骤,那么我可以访问元素方法。
我的元素:
<link rel="import" href="../../components/polymer/polymer.html" />
<dom-module is="app-login">
<template>
<style>
:host { display: block; }
:host.hide { display: none; }
</style>
<div> samle content </div>
</template>
<script>
Polymer({
is: 'app-login',
run: function() {
return new Promise(function(resolve, reject) {
resolve({'id':0,'name':'user'});
});
},
close: function() {
this.classList.add('hide');
}
});
</script>
</dom-module>
我的程序:
// [...]
// this works fine, I just add for better understanding
getTemplate( templateName ) {
return new Promise(function(resolve, reject)
{
fetch( 'templates/'+templateName+'.html' ).then(response => {
document.getElementById('templates').innerHTML += response.text();
resolve(response);
}).catch(error => { reject(error); });
});
};
// [...]
// this method called by the main program and cant't access to the element methods
doLogin() {
this.getTemplate('login').then(templateResponse => {
let Login = document.querySelector('app-login'); // <app-login>...</app-login>
Login.run(); // TypeError: Login.run is not a function
});
};
// [...]
templates/login.html:
<link rel="import" href="elements/app-login/app-login.html" />
<app-login></app-login>
控制台调试:
let Login = document.querySelector('app-login');
//Return: <app-login>...</app-login>
Login.run();
//Return: Promise {[[PromiseStatus]]: "pending", [[PromiseValue]]: undefined}
我试过搜索这个但是我找不到任何相关的答案,以前有人用某种方式解决过这个问题吗?
已经尝试过:
- 将元素添加到 DOM 后设置超时 » 同样的结果
- 将 _ 添加到方法名称(如纸元素方法)» 相同的结果
- 将元素插入 DOM 后等待 WebComponentsReady 事件 » 事件未触发,程序停止
深入研究主题并在 google 上的 polymer-dev 组寻求帮助; Karl Tiedt (@ktiedt) 解决了我的问题:
解决方案是使用 Polymer importHref 和 dom().appendChild 而不是简单的 responseText 追加到容器元素。这些方法不可用,因为元素解析不同,据我所知,如果将 HTML 文本附加到容器的内部 HTML,则 javascript 无法访问元素 shadowDOM。
我更改了 getTemplate 方法以使用 Polymer importHref 并使用 Polymer.dom().appendChild.
附加容器关于 importHref 用法的信息:
https://www.polymer-project.org/1.0/docs/devguide/instance-methods#imports-and-urls
getTemplate( templateName )
{
let templateFile = this.baseURL+'templates/'+templateName+'.html';
return new Promise(function(resolve, reject)
{
let templateRequest = Polymer.Base.importHref(templateFile,
function()
{
Polymer.dom(document.getElementById('templates'))
.appendChild(templateRequest.import.body);
resolve(templateRequest);
},
function(error)
{
reject(error);
});
});
};