mirror of
https://github.com/NativeScript/NativeScript.git
synced 2025-08-16 03:31:45 +08:00
Merge pull request #1679 from NativeScript/hdeshev/listview-proxycontainer-child
Fix a crash when using a ProxyViewContainer in ListView item templates.
This commit is contained in:
@ -8,6 +8,7 @@ import {LayoutBase} from "ui/layouts/layout-base"
|
|||||||
import {StackLayout} from "ui/layouts/stack-layout"
|
import {StackLayout} from "ui/layouts/stack-layout"
|
||||||
import {GridLayout} from "ui/layouts/grid-layout"
|
import {GridLayout} from "ui/layouts/grid-layout"
|
||||||
import {ProxyViewContainer} from "ui/proxy-view-container";
|
import {ProxyViewContainer} from "ui/proxy-view-container";
|
||||||
|
import {ListView} from "ui/list-view";
|
||||||
|
|
||||||
export function test_add_children_to_attached_proxy() {
|
export function test_add_children_to_attached_proxy() {
|
||||||
var outer = new StackLayout();
|
var outer = new StackLayout();
|
||||||
@ -224,6 +225,25 @@ export function test_proxy_iniside_border() {
|
|||||||
helper.buildUIAndRunTest(scroll, testAction);
|
helper.buildUIAndRunTest(scroll, testAction);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function test_proxy_iniside_listview_itemtemplate_crash() {
|
||||||
|
// Usually reproducible with an Angular component in the template
|
||||||
|
// We use a simple declaration here to simulate it.
|
||||||
|
var list = new ListView();
|
||||||
|
list.items = ["item 1"];
|
||||||
|
list.itemTemplate = `
|
||||||
|
<ProxyViewContainer>
|
||||||
|
<Label text="{{$value}}"></Label>
|
||||||
|
</ProxyViewContainer>
|
||||||
|
`;
|
||||||
|
|
||||||
|
function testAction(views: Array<View>) {
|
||||||
|
var page = <Page>views[1];
|
||||||
|
waitUntilElementLayoutIsValid(page);
|
||||||
|
};
|
||||||
|
|
||||||
|
helper.buildUIAndRunTest(list, testAction);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Proxy as a direct child to of TabItem is not supported. Not sure if we want to support it.
|
// TODO: Proxy as a direct child to of TabItem is not supported. Not sure if we want to support it.
|
||||||
//export function test_proxy_iniside_tab() {
|
//export function test_proxy_iniside_tab() {
|
||||||
// var proxy = new ProxyViewContainer();
|
// var proxy = new ProxyViewContainer();
|
||||||
|
@ -6,6 +6,7 @@ import proxy = require("ui/core/proxy");
|
|||||||
import dependencyObservable = require("ui/core/dependency-observable");
|
import dependencyObservable = require("ui/core/dependency-observable");
|
||||||
import definition = require("ui/list-view");
|
import definition = require("ui/list-view");
|
||||||
import utils = require("utils/utils")
|
import utils = require("utils/utils")
|
||||||
|
import {ProxyViewContainer} from "ui/proxy-view-container";
|
||||||
import * as layoutBase from "ui/layouts/layout-base";
|
import * as layoutBase from "ui/layouts/layout-base";
|
||||||
import * as colorModule from "color";
|
import * as colorModule from "color";
|
||||||
|
|
||||||
@ -229,7 +230,10 @@ function ensureListViewAdapterClass() {
|
|||||||
}
|
}
|
||||||
this._listView._prepareItem(args.view, index);
|
this._listView._prepareItem(args.view, index);
|
||||||
if (!args.view.parent) {
|
if (!args.view.parent) {
|
||||||
if (args.view instanceof layoutBase.LayoutBase) {
|
// Proxy containers should not get treated as layouts.
|
||||||
|
// Wrap them in a real layout as well.
|
||||||
|
if (args.view instanceof layoutBase.LayoutBase &&
|
||||||
|
!(args.view instanceof ProxyViewContainer)) {
|
||||||
this._listView._addView(args.view);
|
this._listView._addView(args.view);
|
||||||
convertView = args.view.android;
|
convertView = args.view.android;
|
||||||
} else {
|
} else {
|
||||||
|
@ -4,6 +4,8 @@ import common = require("./list-view-common");
|
|||||||
import utils = require("utils/utils");
|
import utils = require("utils/utils");
|
||||||
import view = require("ui/core/view");
|
import view = require("ui/core/view");
|
||||||
import proxy = require("ui/core/proxy");
|
import proxy = require("ui/core/proxy");
|
||||||
|
import {StackLayout} from "ui/layouts/stack-layout";
|
||||||
|
import {ProxyViewContainer} from "ui/proxy-view-container";
|
||||||
import dependencyObservable = require("ui/core/dependency-observable");
|
import dependencyObservable = require("ui/core/dependency-observable");
|
||||||
import * as colorModule from "color";
|
import * as colorModule from "color";
|
||||||
|
|
||||||
@ -322,11 +324,18 @@ export class ListView extends common.ListView {
|
|||||||
let args = notifyForItemAtIndex(this, cell, view, ITEMLOADING, indexPath);
|
let args = notifyForItemAtIndex(this, cell, view, ITEMLOADING, indexPath);
|
||||||
view = args.view || this._getDefaultItemContent(indexPath.row);
|
view = args.view || this._getDefaultItemContent(indexPath.row);
|
||||||
|
|
||||||
|
// Proxy containers should not get treated as layouts.
|
||||||
|
// Wrap them in a real layout as well.
|
||||||
|
if (view instanceof ProxyViewContainer) {
|
||||||
|
var sp = new StackLayout();
|
||||||
|
sp.addChild(view);
|
||||||
|
view = sp;
|
||||||
|
}
|
||||||
|
|
||||||
// If cell is reused be have old content - remove it first.
|
// If cell is reused be have old content - remove it first.
|
||||||
if (!cell.view) {
|
if (!cell.view) {
|
||||||
cell.owner = new WeakRef(view);
|
cell.owner = new WeakRef(view);
|
||||||
}
|
} else if (cell.view !== view) {
|
||||||
else if (cell.view !== view) {
|
|
||||||
this._removeContainer(cell);
|
this._removeContainer(cell);
|
||||||
(<UIView>cell.view._nativeView).removeFromSuperview();
|
(<UIView>cell.view._nativeView).removeFromSuperview();
|
||||||
cell.owner = new WeakRef(view);
|
cell.owner = new WeakRef(view);
|
||||||
@ -341,8 +350,7 @@ export class ListView extends common.ListView {
|
|||||||
}
|
}
|
||||||
|
|
||||||
cellHeight = this._layoutCell(view, indexPath);
|
cellHeight = this._layoutCell(view, indexPath);
|
||||||
}
|
} finally {
|
||||||
finally {
|
|
||||||
this._preparingCell = false;
|
this._preparingCell = false;
|
||||||
}
|
}
|
||||||
return cellHeight;
|
return cellHeight;
|
||||||
|
Reference in New Issue
Block a user