视口刷新后聚合物 DOM 更新
Polymer DOM update after viewport refresh
我一直在努力解决这个问题,但到目前为止一直找不到答案。我的 Polymer 元素加载了一个基本模板 JSON 文件,然后 运行 通过 dom-repeat
创建一个基本 HTML 页面。
然后加载另一个 JSON 文本文件,用 JS 函数完成 HTML 的各个区域。
单击子表单按钮后,一个函数 运行 会触发加载另一个 JSON 文件以添加附加信息。这一切都很好。
但是,当我离开页面并返回时,它已经记住了我的所有设置,但无法正确显示内容。它很好地显示了 translatedText
并且存在 html 代码,但是它没有完成 originalText
.
的 html 代码
似乎要在 DOM 正确呈现之前加载最后一个 JSON 文件。所以我想让它刷新整个 DOM,但是我该怎么做呢?
我的 MWE:
<template>
<iron-ajax
auto
url="basetext.json"
handle-as="json"
last-response="{{baseText}}"></iron-ajax>
<div class="textcontent">
<template is="dom-repeat" items="{{baseText.lines}}" as="line">
<div class="lineblock">
<div class="line" id="line{{line.lineid}}" inner-h-t-m-l="{{line.linetext}}"></div>
<template is="dom-if" if="[[extraShowEnabled]]">
<div class="linepi" id='linepi{{line.lineid}}' inner-h-t-m-l="{{line.linetext}}"></div>
</template>
</div>
</template>
</div>
<template is="dom-if" if="[[extraLoadEnabled]]">
<iron-ajax
auto
url="originaltext.json"
handle-as="json"
last-response="{{originalText}}"></iron-ajax>
</template>
<iron-ajax
auto
url="translatedtext.json"
handle-as="json"
last-response="{{translatedText}}"></iron-ajax>
</template>
<script>
Polymer({
is: 'text-page',
properties: {
translatedText: Object,
originalText: Object,
extraShowEnabled: {
type: Boolean,
value: false
},
extraLoadEnabled: {
type: Boolean,
value: false
},
showViewer: {
type: String,
value: "none"
}
},
observers: [
'setView(showViewer)',
' _computeSegments(translatedText,".line")',
' _computeSegments(originalText,".linepi")'
],
ready: function() {
this.addEventListener('eventFromChild', this.changeView);
},
changeView: function(event) {
this.showViewer = event.detail.selectedView;
},
setView: function(showViewer) {
\ first some code here to reset all css.
if (showViewer === "none") {
this.extraShowEnabled = false;
this.extraLoadEnabled = false;
}
if (showViewer === "sidebyside") {
this.extraShowEnabled = true;
this.extraLoadEnabled = true;
this._computeSegments(this.originalText,".linepi");
this._addSideBySideCode();
}
},
_computeSegments: function(inputText,linetype) {
if (inputText) {
Array.from(this.querySelectorAll(linetype+" sc-segment")).forEach(item => item.innerHTML = inputText.segments[item.id]);
}
},
_addSideBySideCode: function() {
\ this function just adds some css.
},
});
</script>
我认为您应该尝试使用计算函数结果作为 dom-重复项目源,像这样:
<template is="dom-repeat" items="{{itmesByParamsCompute(baseText, originalText, translatedText, extraloadEnabled, ...)}}" as="line">
添加您需要重新计算的尽可能多的参数。然后该计算函数应该 return 任何时候至少有一个参数发生变化的有效来源。
另外请记住,如果这些参数中的任何一个未定义,计算函数可能会被完全忽略。解决这个问题的方法是采用相反的方式 - 一个 属性 是从 manny observers 修改而来的,像这样:
properties: {
items_to_use: {
type: Array,
value: []
},
translatedText: {
type: Object,
observer: 'updateItemsToUse'
},
originalText: {
type: Object,
observer: 'updateItemsToUse'
}
},
updateItemsToUse: function (data) {
let updatedArray = this.someMixFixFunction(this.item_to_use, data);
this.set('items_to_use', updatedArray);
},
someMixFixFunction: function (old_array, data_to_apply) {
// do some merging or what ever You need here, for example
let updatedArray = old_array.concat(data_to_apply);
return updatedArray;
}
我一直在努力解决这个问题,但到目前为止一直找不到答案。我的 Polymer 元素加载了一个基本模板 JSON 文件,然后 运行 通过 dom-repeat
创建一个基本 HTML 页面。
然后加载另一个 JSON 文本文件,用 JS 函数完成 HTML 的各个区域。
单击子表单按钮后,一个函数 运行 会触发加载另一个 JSON 文件以添加附加信息。这一切都很好。
但是,当我离开页面并返回时,它已经记住了我的所有设置,但无法正确显示内容。它很好地显示了 translatedText
并且存在 html 代码,但是它没有完成 originalText
.
似乎要在 DOM 正确呈现之前加载最后一个 JSON 文件。所以我想让它刷新整个 DOM,但是我该怎么做呢?
我的 MWE:
<template>
<iron-ajax
auto
url="basetext.json"
handle-as="json"
last-response="{{baseText}}"></iron-ajax>
<div class="textcontent">
<template is="dom-repeat" items="{{baseText.lines}}" as="line">
<div class="lineblock">
<div class="line" id="line{{line.lineid}}" inner-h-t-m-l="{{line.linetext}}"></div>
<template is="dom-if" if="[[extraShowEnabled]]">
<div class="linepi" id='linepi{{line.lineid}}' inner-h-t-m-l="{{line.linetext}}"></div>
</template>
</div>
</template>
</div>
<template is="dom-if" if="[[extraLoadEnabled]]">
<iron-ajax
auto
url="originaltext.json"
handle-as="json"
last-response="{{originalText}}"></iron-ajax>
</template>
<iron-ajax
auto
url="translatedtext.json"
handle-as="json"
last-response="{{translatedText}}"></iron-ajax>
</template>
<script>
Polymer({
is: 'text-page',
properties: {
translatedText: Object,
originalText: Object,
extraShowEnabled: {
type: Boolean,
value: false
},
extraLoadEnabled: {
type: Boolean,
value: false
},
showViewer: {
type: String,
value: "none"
}
},
observers: [
'setView(showViewer)',
' _computeSegments(translatedText,".line")',
' _computeSegments(originalText,".linepi")'
],
ready: function() {
this.addEventListener('eventFromChild', this.changeView);
},
changeView: function(event) {
this.showViewer = event.detail.selectedView;
},
setView: function(showViewer) {
\ first some code here to reset all css.
if (showViewer === "none") {
this.extraShowEnabled = false;
this.extraLoadEnabled = false;
}
if (showViewer === "sidebyside") {
this.extraShowEnabled = true;
this.extraLoadEnabled = true;
this._computeSegments(this.originalText,".linepi");
this._addSideBySideCode();
}
},
_computeSegments: function(inputText,linetype) {
if (inputText) {
Array.from(this.querySelectorAll(linetype+" sc-segment")).forEach(item => item.innerHTML = inputText.segments[item.id]);
}
},
_addSideBySideCode: function() {
\ this function just adds some css.
},
});
</script>
我认为您应该尝试使用计算函数结果作为 dom-重复项目源,像这样:
<template is="dom-repeat" items="{{itmesByParamsCompute(baseText, originalText, translatedText, extraloadEnabled, ...)}}" as="line">
添加您需要重新计算的尽可能多的参数。然后该计算函数应该 return 任何时候至少有一个参数发生变化的有效来源。
另外请记住,如果这些参数中的任何一个未定义,计算函数可能会被完全忽略。解决这个问题的方法是采用相反的方式 - 一个 属性 是从 manny observers 修改而来的,像这样:
properties: {
items_to_use: {
type: Array,
value: []
},
translatedText: {
type: Object,
observer: 'updateItemsToUse'
},
originalText: {
type: Object,
observer: 'updateItemsToUse'
}
},
updateItemsToUse: function (data) {
let updatedArray = this.someMixFixFunction(this.item_to_use, data);
this.set('items_to_use', updatedArray);
},
someMixFixFunction: function (old_array, data_to_apply) {
// do some merging or what ever You need here, for example
let updatedArray = old_array.concat(data_to_apply);
return updatedArray;
}