用复选框重复控制?

Bru*_*ski 0 xpages

我有一个显示视图的重复控件.我现在想要包含一个复选框,以便我可以对所选文档执行操作.添加复选框没有问题,但是如何检查复选框是否已选中,然后转到该行的关联文档?

我的想法是:

  1. 使复选框更改事件从数组范围变量添加或删除文档的UNID.然后只对该数组中的文档执行操作.

  2. 忘记复选框,只需弹出一个列表框,允许用户从中进行选择.

但是有更简单的方法吗?

Tim*_*ony 9

为了获得最大的灵活性,最好不要将我们的用户界面组件直接绑定到数据上; 相反,如果我们引入一个中间的"数据模型"层(通常是描述数据代表的真实世界对象/人/过程的层,而不是在"文档"中思考,这最终只是证明这些真实的 - 世界存在的东西),我们的UI代码变得非常干净,易于理解,易于维护.当我们继续在文档中思考时,它还可以更容易地引入令人沮丧的功能.

例如,假设我们使用扩展库中的对象数据源来创建一个任意对象(例如,让我们调用它pendingRequests),以后我们可以将我们的重复控件绑定到(而不是直接将它绑定到视图):

// Create an empty array to return at the end:
var results = [];

// Create a view navigator instance for iterating the view contents:
var pendingView = database.getView("pendingRequests");
var entryNavigator = pendingView.createViewNav();

var eachEntry = entryNavigator.getFirst();
while (eachEntry != null) {
    // Add metadata about each entry to result array:
    var metaData = eachEntry.getColumnValues();
    results.push({
        startDate: metaData.get(0).getDateOnly(),
        endDate: metaData.get(1).getDateOnly(),
        employeeName: metaData.get(2),
        status: metaData.get(3),
        unid: eachEntry.getUniversalID(),
        selected: "0"
    });
    // In case any column values were Domino objects:
    recycleAll(metaData);
    // Cruise on to the next:
    eachEntry = navigateToNext(entryNavigator, eachEntry);
}

// Final Domino handle cleanup:
recycleAll(entryNavigator, pendingView);

// Return our now populated array:
return results;
Run Code Online (Sandbox Code Playgroud)

在继续之前,我应该指出,上面的例子包括两个非平台原生的语法糖果:recycleAll()navigateToNext().这两个都只是实用功能,使愚蠢的recycle东西更容易处理:

recycleAll

 * More convenient recycling
 */
function recycleAll() {
    for(var i = 0; i < arguments.length; i++) {
        var eachObject = arguments[i];
        // assume this is a collection
        try {
            var iterator = eachObject.iterator();
            while (iterator.hasNext()) {
                recycleAll(iterator.next());
            }
        } catch (collectionException) {
            try {
                eachObject.recycle();
            } catch (recycleException) {
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

navigateToNext

/*
 * Safe way to navigate view entries
 */
function navigateToNext(navigator, currentEntry) {
    var nextEntry = null;
    try {
        nextEntry = navigator.getNext(currentEntry);
    } catch (e) {
    } finally {
        recycleAll(currentEntry);
    }
    return nextEntry;
}
Run Code Online (Sandbox Code Playgroud)

好的,现在回到数据模型......具体来说,这个块:

var metaData = eachEntry.getColumnValues();
results.push({
    startDate: metaData.get(0).getDateOnly(),
    endDate: metaData.get(1).getDateOnly(),
    employeeName: metaData.get(2),
    status: metaData.get(3),
    unid: eachEntry.getUniversalID(),
    selected: "0"
});
Run Code Online (Sandbox Code Playgroud)

因此,对于每个视图条目,我们创建一个非常简单的对象,其中包含我们希望允许用户与之交互的所有相关信息,以及为我们自己的代码提供方便的两个额外属性:unid允许返回到我们需要的文件,并且selected,它为我们提供了一种方法来将复选框绑定到此元数据对象的属性...这意味着用户可以通过复选框切换其值.

所以这是我们如何向用户表示这些数据的基本示例:

<ul style="list-style-type: none;">
    <xp:repeat var="vacationRequest" value="#{pendingRequests}">
        <li style="margin-bottom:10px;">
            <strong>
                <xp:checkBox value="#{vacationRequest.selected}" text="#{vacationRequest.startDate} - #{vacationRequest.endDate}"
                    checkedValue="1" uncheckedValue="0" />
            </strong>
            <xp:text value="#{vacationRequest.employeeName} (#{vacationRequest.status})" tagName="div" />
        </li>
    </xp:repeat>
</ul>
Run Code Online (Sandbox Code Playgroud)

重复控件中的每个复选框现在直接绑定到selected元数据对象的属性,每个"行"代表...也具有unid属性,因此对与此数据模型对应的实际文档进行操作很简单:

for (var i = 0; i < pendingRequests.length; i++) {
    var eachRequest = pendingRequests[i];
    if (eachRequest.selected == "1") {
        var requestDataSource = database.getDocumentByUNID(eachRequest.unid);
        requestDataSource.replaceItemValue("status", "Approved");
        if (requestDataSource.save()) {
            // update in-memory metadata:
            eachRequest.status = "Approved";
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

由于我们的数据源只是这些元数据对象的数组,我们可以循环遍历每个,询问用户是否切换了selected每个元素的属性,如果是,则获取其相应文档的句柄,修改一个或多个项目,并保存.注意:因为我们在此示例中使用了数据源,所以它不会在每个事件上重新加载后端视图数据.出于性能原因,这是一个非常好的事情(tm).但它确实意味着我们必须更新内存中的元数据对象,以匹配我们改变了对文件(即eachRequest.status = "Approved")...但它也意味着我们可以更新只能说,而不必放弃我们的整个数据源,并有它从视图中读回所有内容.

作为奖励,添加诸如"全选"按钮之类的东西甚至更简单:

for (var i = 0; i < pendingRequests.length; i++) {
    pendingRequests[i].selected = "1";
}
Run Code Online (Sandbox Code Playgroud)

因此,总而言之,我们有一个内存数据模型,在许多情况下,等效操作将更快地执行,但也允许我们编写更少的代码 - 更可读的代码 - 来做更好的事情.

如果你想现场玩这个模式(和/或在上下文中下载所有上述源代码),我在这里永生.