在QML中访问父函数

时间:2012-08-01 16:08:27

标签: javascript qml blackberry-10

我目前正在创建一个Twitter客户端,作为学习黑莓10开发的一种方式。我目前正在尝试为自定义ListView项创建一个上下文菜单,在选择时将在主布局中显示一个对话框。但是,我无法让所选列表项从父页面调用任何函数。

以下是我的自定义列表项中的QML:

import bb.cascades 1.0

Container {

    property alias avatar: tracker.imageSource
    property alias username: txtTweetUser.text
    property alias tweetText: txtTweetContent.text
    property alias tweetTime: txtTweetTime.text

    signal sendReply(string username)

    function cout(text) {
        console.debug("[DEBUG] " + text);
    }

    id: itemTweet

    preferredWidth: 768;
    preferredHeight: 200

    // Actions
    contextActions: [
        ActionSet {


            title: "Action Set"
            subtitle: "This is an action set."

            actions: [
                ActionItem {                    
                    title: "Reply"
                    imageSource: "asset:///reply.png"
                    onTriggered: {
                        itemTweet.sendReply(txtTweetUser.text);
                    }
                },
                ActionItem {
                    title: "Retweet"
                    imageSource: "asset:///retweet.png"
                },
                ActionItem {
                    title: "Favourite"
                    imageSource: "asset:///fav.png"
                }
            ]
        } // end of ActionSet   
    ] // end of contextActions list

   <Layout for the List Item>...

    }
}

对于主要的QML文件:

import bb.cascades 1.0

TabbedPane {
    id: tabbedPane
    showTabsOnActionBar: true

    Tab {
        id: tabTimeline
        title: "Timeline"
        imageSource: "asset:///twitter-white.png"

        Page {         
            id: pageTimeline

            signal openReply
            signal showNewTweet

            function cout(text) {
            console.debug("[DEBUG] " + text);
        }

            function showTweetWindow(username) {
                pageTimeline.dialogNewTweet.text = username;
                pageTimeline.dialogNewTweet.visible = true;
            }

            // Title bar
            titleBar: TitleBar {
                visibility: Overlay
                title: "Twitter"

                acceptAction: ActionItem {
                    id: btnNewTweet
                    title: "+"
                    ActionBar.placement: ActionBarPlacement.OnBar
                    onTriggered: {
                       pageTimeline.cout("action selected");
                       dialogNewTweet.visible = true;
                    }
                }
            }

            // Main content
            content: Container {

                layout: AbsoluteLayout {}

                Container { 
                    // Listview for the tweets
                    ListView {
                        id: lstTweets
                        objectName: "lstTweets"                 

                // Components to display the rows                   
                        listItemComponents: [
                            ListItemComponent {
                                id: listItem
                                type: "listItem"
                                TweetItem {                                                                                     
                                    tweetText: ListItemData.content
                                    tweetTime: ListItemData.time
                                    avatar: ListItemData.avatar
                                    username: ListItemData.username

                                    onSendReply: {
                                        cout("Reply selected in parent to " + username);
                                        pageTimeline.showTweetWindow(username);
                                    }
                                }
                            }
                        ]

                        onSelectionChanged: {
                        }

                        function itemType(data, indexPath) {
                            if (indexPath.length == 1) {
                                return "header";
                            } else {
                                return "listItem";
                            }
                        } 

                    }
                }

                DialogNewTweet {
                    id: dialogNewTweet
                    visible: false

                    onShowNewTweet: {
                        dialogNewTweet.visible = true;
                    }
                }

            }
            // End container    
        }
    }
    ... <Other tabs> ...

}

因此,当主QML文件收到SendReply信号时,它会调用showTweetWindow(username)然后使dialogNewTweet可见,但我得到错误ReferenceError: Can't find variable: pageTimeline。这绝对是一个范围问题,但我无法弄清楚我做错了什么,或者我是否需要对其进行重组。

1 个答案:

答案 0 :(得分:3)

在这里回答:

https://community.blackberry.com/message/182467#182467

  

我需要实现的是对数据列表进行操作,例如在QML中使用ListItem中的ContextAction删除项目,然后在QmlDocument的contextProperty中调用对象的C ++方法。我是这样做的:

     

C ++代码:

QmlDocument *qml = QmlDocument::create("accounts.qml");
root = qml->createRootNode<AbstractPane>();

//Here set the context property, accountsManager was already created
qml->setContextProperty("accountsManager", accountsManager);

//Set the model for the list view
ListView* accountsListView = root->findChild<ListView*>("accountsListView");
accountsListView->setDataModel(accountsManager->getDataModel());
     

QML代码:

Page {
    content: Container {     
        ListView {
            id: listView
            objectName: "accountsListView"     

        listItemComponents: [
                ListItemComponent {
                    type: "listItem"
                    StandardListItem{
                        id: accountItem
                        title: ListItemData.username                        
                        contextActions: [
                            ActionSet {
                                deleteAction: DeleteActionItem {
                                    title: "Delete"
                                    onTriggered: {
                                        //it does not work here, "ReferenceError: Can't find variable: accountsManager"
                                        accountsManager.doSometing();
                                    }
                                }
                            }
                        ]
                    }
                } 
            ]

        function itemType(data, indexPath) {
            return "listItem";
          }     
        } // end of ListView
    } // end of Container

    actions: [
        ActionItem {
            title: "Add account"
            ActionBar.placement: ActionBarPlacement.OnBar

            onTriggered: {
                //It works fine here
                accountsManager.doSomething();
            }
        }
    ]
} // end of Page

另一种方法:

https://community.blackberry.com/message/453794#453794

  

在首页级别添加以下行以使标签可访问。

Page {
    id: topPage    
    onCreationCompleted: { Qt.topLabel = topLabel; }
     

然后在按钮定义中,您可以从列表中引用Qt.topLabel。

    listItemComponents: [
            ListItemComponent {
                type: "item"
                Button {
                    text: "Change To Three"
                    onClicked: {
                        Qt.topLabel.text = "Three";
                    }                        
                }
            }
        ]