Repository: DevExpress/devextreme-react
Pull request #288 (2019-01-22 15:06:43)

Fix ghost templates issue
Cherry-pick


Patch:
diff --git a/example/list-example.tsx b/example/list-example.tsx
index 9262669..6a8c7e0 100644
--- a/example/list-example.tsx
+++ b/example/list-example.tsx
@@ -3,7 +3,7 @@ import * as React from "react";
 import DataSource from "devextreme/data/data_source";
 
 import Button from "../src/button";
-import List from "../src/list";
+import List, { Item as ListItem } from "../src/list";
 import TextBox from "../src/text-box";
 
 import Example from "./example-block";
@@ -80,6 +80,13 @@ export default class extends React.Component<any, { text: string; items: IListIt
     public render() {
         return (
             <Example title="DxList" state={this.state} >
+                <hr />
+                <h4>List with inline items</h4>
+                <List>
+                    <ListItem>abc</ListItem>
+                    <ListItem>def</ListItem>
+                    <ListItem>ghi</ListItem>
+                </List>
                 <hr />
                 <h4>List with function template</h4>
                 <List
diff --git a/src/core/helpers.ts b/src/core/helpers.ts
index 2d8acd2..92d1eb8 100644
--- a/src/core/helpers.ts
+++ b/src/core/helpers.ts
@@ -19,3 +19,7 @@ export function addPrefixToKeys(obj: Record<string, any>, prefix: string): Recor
 export function generateID(): string {
     return Math.random().toString(36).substr(2);
 }
+
+export function isEmptyObject(obj: Record<any, any>): boolean {
+    return Object.keys(obj).length === 0;
+}
diff --git a/src/core/options-manager.ts b/src/core/options-manager.ts
index 44912cb..8885a12 100644
--- a/src/core/options-manager.ts
+++ b/src/core/options-manager.ts
@@ -1,6 +1,6 @@
 import { ITemplateMeta } from "./template";
 
-import { addPrefixToKeys, getNestedValue } from "./helpers";
+import { addPrefixToKeys, getNestedValue, isEmptyObject } from "./helpers";
 import { createOptionComponent, INestedOptionMeta } from "./nested-option";
 import TemplateHost from "./template-host";
 import { separateProps } from "./widget-config";
@@ -214,9 +214,13 @@ class OptionsManager {
                 configComponent.defaults,
                 configComponent.templates);
 
+            const nestedObjects = this._getNestedOptionsObjects(e.children, templateRegistrationRequired);
+
             if (templateRegistrationRequired) {
                 this._templateHost.add({
-                    useChildren: (optionName) => optionName === "template" && !!e.element.props.children,
+                    useChildren: (optionName) => {
+                        return optionName === "template" && !!e.element.props.children && isEmptyObject(nestedObjects);
+                    },
                     props: props.templates,
                     templateProps: configComponent.templates,
                     ownerName: this.buildFullOptionName(
@@ -231,7 +235,7 @@ class OptionsManager {
                 ...e.predefinedProps,
                 ...props.defaults,
                 ...props.options,
-                ...this._getNestedOptionsObjects(e.children, templateRegistrationRequired)
+                ...nestedObjects
             };
         });
 


Test patch:
diff --git a/src/core/__tests__/template.test.tsx b/src/core/__tests__/template.test.tsx
index cdaea21..2bb37fd 100644
--- a/src/core/__tests__/template.test.tsx
+++ b/src/core/__tests__/template.test.tsx
@@ -496,6 +496,10 @@ describe("component/render in nested options", () => {
                     <UserTemplate/>
                 </CollectionNestedComponent>
                 <CollectionNestedComponent/>
+                <CollectionNestedComponent>
+                    <NestedComponent/>
+                    <UserTemplate/>
+                </CollectionNestedComponent>
             </TestComponent>
         );
 
@@ -504,6 +508,7 @@ describe("component/render in nested options", () => {
         expect(options["collection[0].template"]).toBe("collection[0].template");
         expect(options["collection[1].template"]).toBe("collection[1].template");
         expect(options["collection[2].template"]).toBe(undefined);
+        expect(options["collection[3].template"]).toBe(undefined);
         expect(options["option.item"]).toBe(undefined);
         expect(options["option.template"]).toBe(undefined);