为什么changeDetectionStrategy.OnPush不会在@Input属性更改中更新但更新@Output触发器属性更改?

时间:2017-10-19 03:08:07

标签: javascript angular typescript angular2-changedetection

考虑这个plunker

Grandchild Component

<button (click)="back2click()"></button>

@Input() from2;
@Output()
back2 = new EventEmitter<any>();

back2click() {
   this.back2.emit('hi');
}

Child Component

changeDetection: ChangeDetectionStrategy.OnPush,

<my-app-n2 [from2]="from1" (back2)="handleback2($event)"></my-app-n2>

@Input() from1;
@Output() back1 = new EventEmitter<any>();

handleback2() {
    this.back1.emit('hi')
}

Parent Component

<my-app-n1 [from1]="from" (back1)="handleback1($event)"></my-app-n1>
handleback1 () {
    this.from.name = 'handline4';
}

我看到点击button

back2click -> emit -> handleback2 -> emit -> handleback1 
    -> attribute is updated -> all child view are updated

这是令人困惑的,因为我希望只有父视图才能更新,因为changeDetection: ChangeDetectionStrategy.OnPush,是子组件中的配置。

我想我错过了什么,有人能指出正确的方向吗?

由于

1 个答案:

答案 0 :(得分:1)

所有本机事件都标记了根组件的路径以进行一次检查。在FileInputStream in = new FileInputStream("form.pdf"); FileOutputStream out = new FileOutputStream("test.pdf"); PDDocument document = PDDocument.loadNonSeq(in,null); document.setAllSecurityToBeRemoved(false); Map<String, String> values = new HashMap<String, String>(); values.put("imiePracownika", "Grzegorz K."); setFields(document, values); PDAcroForm form = document.getDocumentCatalog().getAcroForm(); Document documentXML = form.getXFA().getDocument(); NodeList dataElements = documentXML.getElementsByTagName("xfa:data"); if (dataElements != null) { for (int i = 0; i < dataElements.getLength(); i++) { setXFAFields(dataElements.item(i), values); } } RandomAccessBuffer r = new RandomAccessBuffer(); COSStream cosout = new COSStream(r); TransformerFactory.newInstance().newTransformer().transform(new DOMSource(documentXML), new StreamResult(cosout.createUnfilteredStream())); form.setXFA(new PDXFA(cosout)); document.save(out); document.close(); private void setFields(PDField field, Map<String, String> values) throws IOException { List<COSObjectable> kids = field.getKids(); if (kids != null) { for (COSObjectable pdfObj : kids) { if (pdfObj instanceof PDField) { setFields((PDField) pdfObj, values); } } } else { // remove the [0] from the name to match values in our map String partialName = field.getPartialName().replaceAll("\\[\\d\\]", ""); if (!(field instanceof PDSignatureField) && values.containsKey(partialName)) { field.setValue(values.get(partialName)); } } } public void setFields(PDDocument pdfDocument, Map<String, String> values) throws IOException { @SuppressWarnings("unchecked") List<PDField> fields = pdfDocument.getDocumentCatalog().getAcroForm().getFields(); for (PDField pdField : fields) { setFields(pdField, values); } } public void setXFAFields(Node pNode, Map<String, String> values) throws IOException { if (values.containsKey(pNode.getNodeName())) { pNode.setTextContent(values.get(pNode.getNodeName())); } else { NodeList childNodes = pNode.getChildNodes(); if (childNodes != null) { for (int i = 0; i < childNodes.getLength(); i++) { setXFAFields(childNodes.item(i), values); } } } } 模板中,您使用的是原生Grandchild Component事件:

click

因此,组件的层次结构被标记为一次检查。

<button (click)="back2click()"></button>

有关变化检测的最全面解释,请阅读:

要详细了解 Root Component -> ViewState.ChecksEnabled = true | ... | Parent -> ViewState.ChecksEnabled = true | | Child (onPush) -> ViewState.ChecksEnabled = true | | Grand child (event triggered here) -> markForCheck() -> ViewState.ChecksEnabled = true ,请参阅this answer并阅读本文: