如何将Kendo React Component提取到自己的文件中

时间:2018-01-30 23:24:32

标签: reactjs kendo-react-ui

我正在关注React的Kendo UI online documentation,我遇到了部分问题。在链接的示例中,部分复制在下面,有一个文件包含我想要重用的组件的反应代码。它看起来像:

/**
 A CompoundFetchedResultsController is a wrapper of a number of inner NSFetchedResultsControllers.
 The wrapper flattens the sections produced by the inner controllers, behaving as if all sections
 were fetched by a single controller. Additionally, change notifications are mapped before being
 passed to the optional NSFetchedResultsControllerDelegate property, so that the section indices
 in the notifications reflect the flattened section indicies.

 Example use case: a table where sections should be ordered in mutually opposing ways. E.g., if
 section 1 should be ordered by propery A ascending, but section 2 should be ordered by property A
 descending. In this case, two controllers can be created - one ordering ascending, the other de-
 scending - and wrapped in a CompoundFetchedResultsController. This will maintain the ease of use
 in a UITableViewController, and the functionality provided by a NSFetchedResultsControllerDelegate.
 */
class CompoundFetchedResultsController<T: NSFetchRequestResult>: NSObject, NSFetchedResultsControllerDelegate {

    // The wrapperd controllers
    let controllers: [NSFetchedResultsController<T>]

    // A delegate to notify of changes. Each of the controllers' delegates are set to this class,
    // so that we can map the index paths in the notifications before forwarding to this delegate.
    var delegate: NSFetchedResultsControllerDelegate? {
        didSet { controllers.forEach{$0.delegate = self} }
    }

    init(controllers: [NSFetchedResultsController<T>]) { self.controllers = controllers }

    func performFetch() throws { controllers.forEach{try? $0.performFetch()} }

    var sections: [NSFetchedResultsSectionInfo]? {
        // To get the flattened sections array, we simply reduce-by-concatenation the inner controllers' sections arrays.
        get { return controllers.flatMap{$0.sections}.reduce([], +) }
    }

    private func sectionOffset(forController controller: NSFetchedResultsController<T>) -> Int {
        // Determine the index of the specified controller
        let controllerIndex = controllers.index(of: controller)!

        // Count the number of sections present in all controllers up to (but not including) the supplied controller
        return controllers.prefix(upTo: controllerIndex).map{$0.sections!.count}.reduce(0, +)
    }

    func object(at indexPath: IndexPath) -> T {
        // Sum the section counts of the controllers, in order, until we exceed the section of the supplied index path.
        // At that point, we have identifiers the controller which should be used to obtain the object, and just
        // adjust the supplied index path's section accordingly.
        var sectionCount = 0
        for controller in controllers {
            if sectionCount + controller.sections!.count <= indexPath.section {
                sectionCount += controller.sections!.count
            }
            else {
                return controller.object(at: IndexPath(row: indexPath.row, section: indexPath.section - sectionCount))
            }
        }
        fatalError("Could not find index path \(indexPath).")
    }

    func indexPath(forObject object: T) -> IndexPath? {
        // Given an object, to determine which controller it is in, we just query each controller in turn.
        for controller in controllers {
            if let indexPath = controller.indexPath(forObject: object) {
                return IndexPath(row: indexPath.row, section: sectionOffset(forController: controller) + indexPath.section)
            }
        }
        return nil
    }

    func controllerWillChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
        // Forward on the willChange notification
        delegate?.controllerWillChangeContent?(controller)
    }

    func controllerDidChangeContent(_ controller: NSFetchedResultsController<NSFetchRequestResult>) {
        // Forward on the didlChange notification
        delegate?.controllerDidChangeContent?(controller)
    }

    func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange anObject: Any, at indexPath: IndexPath?, for type: NSFetchedResultsChangeType, newIndexPath: IndexPath?) {

        let sectionOffset = self.sectionOffset(forController: controller as! NSFetchedResultsController<T>)

        // Index Paths should be adjusted by adding to the section offset to the section index
        func adjustIndexPath(_ indexPath: IndexPath?) -> IndexPath? {
            guard let indexPath = indexPath else { return nil }
            return IndexPath(row: indexPath.row, section: indexPath.section + sectionOffset)
        }

        // Forward on the notification with the adjusted index paths
        delegate?.controller?(controller, didChange: anObject, at: adjustIndexPath(indexPath), for: type, newIndexPath: adjustIndexPath(newIndexPath))
    }

    func controller(_ controller: NSFetchedResultsController<NSFetchRequestResult>, didChange sectionInfo: NSFetchedResultsSectionInfo, atSectionIndex sectionIndex: Int, for type: NSFetchedResultsChangeType) {

        let sectionOffset = self.sectionOffset(forController: controller as! NSFetchedResultsController<T>)

        // Forward on the notification with the adjusted section index
        delegate?.controller?(controller, didChange: sectionInfo, atSectionIndex: sectionIndex + sectionOffset, for: type)
    }
}

在同一个文件中是一个实现上述组件的React类。该类的render方法如下所示:

class DropDownCell extends GridCell {
    handleChange(e) {
        this.props.onChange({
            dataItem: this.props.dataItem,
            field: this.props.field,
            syntheticEvent: e.syntheticEvent,
            value: e.target.value
        });
    }
    render() {
        const value = this.props.dataItem[this.props.field];

        if (!this.props.dataItem.inEdit) {
            return (
                <td> {
                    (value === null) ? '' : this.props.dataItem[this.props.field].toString()}
                </td>
            );
        }

        return (
            <td>
                <DropDownList
                    style={{ width: "100px" }}
                    onChange={this.handleChange.bind(this)}
                    value={value}
                    data={[
                        { text: 'yes', value: true },
                        { text: 'no', value: false },
                        { text: '(empty)', value: null }
                    ]}
                    valueField="value"
                    textField="text"
                />
            </td>
        );
    }
}

我想通过网格将数据从我的Grid的父组件向下传递到DropDownCell组件。但每次我尝试创建一个单独的DropDownCell文件并将其导入我的Grid类时,我都无法让DropDownCell继续工作。如何从DropDownCell类在其自己的文件中创建可重用的反应组件并让它在我的网格中呈现?

0 个答案:

没有答案